angular - Angular 无法从 Spring Boot 接收 JWT 令牌
问题描述
我在控制台中收到此错误:
null
dan
TypeError: Cannot read property 'token' of null
at MapSubscriber.project (basic-authentication.service.ts:29)
at MapSubscriber._next (map.js:29)
at MapSubscriber.next (Subscriber.js:49)
at MapSubscriber._next (map.js:35)
at MapSubscriber.next (Subscriber.js:49)
at FilterSubscriber._next (filter.js:33)
at FilterSubscriber.next (Subscriber.js:49)
at MergeMapSubscriber.notifyNext (mergeMap.js:69)
at InnerSubscriber._next (InnerSubscriber.js:11)
at InnerSubscriber.next (Subscriber.js:49)
我正在尝试从 Angular 7 前端对用户进行身份验证。当我使用 Postman 进行测试时,它适用于所有请求(即使使用 JWT 令牌)。
我在 intelliJ 上启用调试器的情况下再次运行登录操作,并且 JWT 已正确创建并发送,但在 Angular 前端应用程序上似乎为空。
***请注意,我可能在 Spring 中处于中间状态,但在 Angular 中确实是新手
这是我的Angular 代码被调用:
executeJWTAuthenticationService(username, password) {
return this.http.post<any>(
`${API_URL}/login`, {
username,
password
}).pipe(
map(
data => {
console.log(data);
console.log(username);
sessionStorage.setItem(AUTHENTICATED_USER, username);
sessionStorage.setItem(TOKEN, `Bearer ${data.token}`);
return data;
}
)
);
}
这是我的JwtAuthenticationFilter:
public class JwtAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
private AuthenticationManager authenticationManager;
public JwtAuthenticationFilter(AuthenticationManager authenticationManager) {
this.authenticationManager = authenticationManager;
}
/* Trigger when we issue POST request to /login
We also need to pass in {"username":"dan", "password":"dan123"} in the request body
*/
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
// Grab credentials and map them to login viewmodel
LoginViewModel credentials = null;
try {
credentials = new ObjectMapper().readValue(request.getInputStream(), LoginViewModel.class);
} catch (IOException e) {
e.printStackTrace();
}
// Create login token
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(
credentials.getUsername(),
credentials.getPassword(),
new ArrayList<>());
// Authenticate user
Authentication auth = authenticationManager.authenticate(authenticationToken);
return auth;
}
@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException {
// Grab principal
UserPrincipal principal = (UserPrincipal) authResult.getPrincipal();
// Create JWT Token
String token = JWT.create()
.withSubject(principal.getUsername())
.withExpiresAt(new Date(System.currentTimeMillis() + JwtProperties.EXPIRATION_TIME))
.sign(HMAC512(JwtProperties.SECRET.getBytes()));
// Add token in response
response.addHeader(JwtProperties.HEADER_STRING, JwtProperties.TOKEN_PREFIX + token);
}
}
解决方案
只需尝试在您的角度 http 调用中观察响应。然后您将能够从响应标头中读取 JWT 令牌。
executeJWTAuthenticationService(username, password) {
return this.http.post<any>(
`${API_URL}/login`, {
username,
password
}, {observe: 'response'}).pipe(
map(
data => {
const token = data.headers.get("Authorization");
console.log(data);
console.log(username);
sessionStorage.setItem(AUTHENTICATED_USER, username);
sessionStorage.setItem(TOKEN, `Bearer ${token}`);
return data;
}
)
);
}
推荐阅读
- swiftmailer - 要在 WAMP 中使用 Swiftmailer,WAMP 中的 /usr/local/lib/php 等价物是什么?
- ios - Cocoapods 错误:无法为“RNCryptor”加载底层模块
- pygame - Pygame 窗口突然没有响应
- c - 错误:一元'*'的无效类型参数(有'int')|
- flutter - 颤动本地通知“一天中的小时,以 24 小时制 [0..23] 表示。”
- wpf - 使用异步和等待实时更新数据
- cassandra - 如何使用图形引擎作为 Janusgraph 和存储后端作为 cassandra 更改 gremlin 中的属性键?
- linux - 安装后无法运行mongoDB
- javascript - 如何在 React 中有条件地设置状态?
- flutter - 在不中断程序执行的情况下使函数在 x 秒后执行