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 中刷新令牌?