Asp.Net Core API 需要认证时发生重定向的解决方法

栏目: ASP.NET · 发布时间: 4年前

内容简介:使用 .Net Core 开发 API 时, 有些 API 是需要认证, 添加了客户端在没有认证之前, 应该返回 401 (未认证)的 HTTP 状态码, 但是在添加了 Identity 认证之后, 返回结果变成了 302 (重定向)。对于浏览器来说, 重定向是正确的, 而 Ajax 请求则会自动继续请求重定向之后的地址, 因此必须解决掉返回重定向的问题。

使用 .Net Core 开发 API 时, 有些 API 是需要认证, 添加了 [Authorize] 标记, 代码如下所示:

[Route("api/[controller]")]
[ApiController]
public class AccountController : Controller {

    [HttpGet("info")]
    [Authorize]
    public async Task<ActionResult<AccountInfoModel>> GetInfo() { }

}

客户端在没有认证之前, 应该返回 401 (未认证)的 HTTP 状态码, 但是在添加了 Identity 认证之后, 返回结果变成了 302 (重定向)。

对于浏览器来说, 重定向是正确的, 而 Ajax 请求则会自动继续请求重定向之后的地址, 因此必须解决掉返回重定向的问题。

既然是通过添加 Identity 认证造成, 肯定要从 Identity 来找问题, 经过一番搜索, 终于在 CookieAuthenticationEvents 中找到了原因, 代码中有关于是否是 Ajax 请求的判断

public Func<RedirectContext<CookieAuthenticationOptions>, Task> OnRedirectToReturnUrl { get; set; } = context =>
{
    if (IsAjaxRequest(context.Request))
    {
        context.Response.Headers[HeaderNames.Location] = context.RedirectUri;
    }
    else
    {
        context.Response.Redirect(context.RedirectUri);
    }
    return Task.CompletedTask;
};

private static bool IsAjaxRequest(HttpRequest request)
{
    return string.Equals(request.Query["X-Requested-With"], "XMLHttpRequest", StringComparison.Ordinal) ||
        string.Equals(request.Headers["X-Requested-With"], "XMLHttpRequest", StringComparison.Ordinal);
}

从上面的代码可以看出, 如果请求的 QueryString 或者 Header 中包含 X-Requested-With 并且值为 XMLHttpRequest 的话, 则会被判断为 AjaxRequest , 将不会返回重定向结果, 问题原因找到了, 解决方法也就有了。

对于 Angular 来说, 可以实现一个全局的 HttpInterceptor , 来添加这个 Header , 代码如下:

export class AuthInterceptor implements HttpInterceptor {

    public intercept(
        req: HttpRequest<any>,
        next: HttpHandler
    ): Observable<HttpEvent<any>> {
        if (req.url.startsWith(environment.apiUrl)) {
            const request = req.clone({
                withCredentials: true,
                setHeaders: {
                    'X-Requested-With': 'XMLHttpRequest'
                }
            });
            return next.handle(request);
        }
        return next.handle(req);
    }
}

最后, 在 app.module.ts 中注册这个拦截器, 代码为:

import { AuthInterceptor } from './services/auth.interceptor';

@NgModule({
    declarations: [
        AppComponent,
    ],
    providers: [
        {
            provide: HTTP_INTERCEPTORS,
            useClass: AuthInterceptor,
            multi: true
        }
    ],
    bootstrap: [AppComponent]
})
export class AppModule {}

现在再次访问需要认证的 API 就不会有重定向结果返回了。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

百度SEM竞价推广

百度SEM竞价推广

马明泽 / 电子工业出版社 / 2017-5 / 59

竞价推广已成为企业昀主要的网络营销方式,《百度SEM竞价推广:策略、方法、技巧与实战》以百度竞价推广为基础,全面阐述了整个竞价推广过程中的重要环节,涉及大量账户操作实战技巧,以及解决各类难点的方法,其中包括搜索引擎营销基础、百度搜索推广介绍、账户结构搭建技巧、关键词与创意的使用技巧、质量度优化与提升、账户工具的使用、百度推广客户端的使用、企业搜索推广方案制作、百度网盟推广、着陆页分析、效果优化与数......一起来看看 《百度SEM竞价推广》 这本书的介绍吧!

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具