Angular:如何通过 API 调用使用 JWT 身份验证

Posted

技术标签:

【中文标题】Angular:如何通过 API 调用使用 JWT 身份验证【英文标题】:Angular : How to use JWT Authentication with an API call 【发布时间】:2018-12-28 08:15:07 【问题描述】:

我正在关注this 的文章。作者正在使用fake-backend.ts拦截一个以/api/authenticate结尾的api调用,并根据用户名和密码从静态数组中检查用户。

当用户使用用户名和密码提交表单时,它会调用authentication.service.ts 登录函数,该函数在路径/api/authenticate 上发布调用,并且由于调用的url 以/api/authenticate 结尾,所以现在fake-backend.ts 发挥作用正在从静态数组验证用户。身份验证成功后,它会生成一个令牌并控制返回到authentication.service.ts 以映射响应对象

我通过调用 api 来验证来自 db 的用户来更改此 fake-backend.ts。但我遇到了错误。

https://localhost:44348/api/authenticate 的 Http 失败响应: 404 确定

也调用不返回authentication.service.ts 来映射响应对象。

if (request.url.endsWith('/api/authenticate') && request.method === 'POST') 
const UserName = request.body.username;
const Password = request.body.password;
var credentials =  UserName, Password ;
//return this.employeeService.autheticateEmployeeByCredentials(credentials);
this.employeeService.autheticateEmployeeByCredentials(credentials).subscribe((res) => 
if (res == 1) 
    return of(new HttpResponse( status: 200, body:  token: 'fake-jwt-token'  ));    
else 
      return throwError( error:  message: 'Username or password is incorrect'  );   
  );
   

编辑: 我正在使用 api 控制器并从返回 1 进行验证,如果它存在于 db else 0 中。也从 api 获得响应,但控制不会返回到 authentication.service.ts,而是转到 login.component.ts 订阅并抛出此错误。

【问题讨论】:

你看过这些博客吗? jasonwatmore.com/post/2016/08/16/…blog.angular-university.io/angular-jwt-authentication 另一个了解 JSON Web 令牌的好资源:blog.angular-university.io/angular-jwt 你的后端是什么,在哪里? 我已经更新了问题请检查编辑部分.. 【参考方案1】:

首先,您的响应中的 404 是 NotFound 响应 - 这意味着您的服务无法看到该网址。 默认情况下,所有来自服务器的不成功响应(状态码在 200-299 范围之外的响应)都被视为错误响应,这意味着它们会触发错误。从表面上看,fake-backend 没有 try-catch 机制,因此 404 不会命中 Promise 链下的任何订阅。

所以为了解决你的问题,我建议你使用像Postman这样的应用程序 验证您的 https://localhost:44348/api 是否确实有效。

然后在它显示return next.handle(request); 的地方,使用catchError 来处理来自您的api 的非成功响应,如下例所示。然后在你的 authentication.service.ts 你可以做类似authenticateUser(/*parameters*/).subscribe(response => if(response.body.error) /*handle error */ else /*do your normal stuff */);

 return next.handle(request).pipe(
              catchError(error => 
                return of(
                  new HttpResponse(
                    status: 200,
                    body: 
                      error: 
                        responseMessage: 'Some Error Accessing API'
                      
                      /**some response body you can surely handle in authentication.service.ts */
                    
                  )
                );
              )
            );

要完全解决您的具体问题,您介意发布完整的 FakeBackendInterceptor 类吗?

【讨论】:

它与文章@gerryc.inc 中的相同,我已粘贴已更改。问题是它没有等待来自后端“autheticateEmployeeByCredentials”验证用户的服务的响应.. 让我们看看 autheticateEmployeeByCredentials 方法。我有兴趣了解它如何处理 HttpClient 调用的结果(我假设您正在使用 HttpClient 服务对后端进行实际调用)。 sry 很抱歉在周末回复晚了,是的,它是一个简单的 httpclient 服务调用支持它没有什么特别的..【参考方案2】:

看起来你有两个问题(或者更多问题),但让我们解决第一个问题......

为了不破坏承诺链,您需要返回对employeeservice 的调用。

另外,您能否确认您的后端正在监听https://localhost:44348/api 而不是您的前端?

【讨论】:

这是我不知道如何在不破坏承诺链的情况下返回服务调用的问题.. 哎呀,抱歉多个答案...我正在使用手机,但没有意识到我正在转发和回答...【参考方案3】:

嗯,看来你在这不合时宜……

在他的例子中,他用那个拦截器伪造了他的后端。

if (request.url.endsWith('/api/authenticate') && request.method === 'POST')  const UserName = request.body.username; const Password = request.body.password; var credentials =  UserName, Password ; //return this.employeeService.autheticateEmployeeByCredentials(credentials); this.employeeService.autheticateEmployeeByCredentials(credentials).subscribe((res) =>  if (res == 1) return of(new HttpResponse( status: 200, body:  token: 'fake-jwt-token'  )); else return throwError( error:  message: 'Username or password is incorrect'  ); );

因此,例如,如果您将使用后端进行身份验证,则应将其删除。

之后,在身份验证服务中,您应该调用后端正在侦听的 url。

【讨论】:

我也试过这个,但是如何生成令牌然后“返回(新的HttpResponse(状态:200,正文:令牌:'fake-jwt-token'));”,也我需要知道 api 0 或 1 的响应是什么。 状态码和标头应该由您的后端设置,而不是您的前端。我建议你,如果你的 api 返回 1 它应该返回响应状态 200 和令牌头。当它返回 0 时,您应该返回带有状态码 401 的响应。

以上是关于Angular:如何通过 API 调用使用 JWT 身份验证的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 jwt 在 Angular 6 和 web api 中刷新令牌?

通过 Angular 4 将 JWT 令牌附加到 api 请求

Angular 2 JWT 单元测试

如何使用 auth0 jwt 识别用户

在 Angular2 中保护 API 密钥

Spring Boot JWT Cors 不适用于 Angular 8