【发布时间】:2021-04-21 00:38:55
【问题描述】:
登录/注册过程正常,但我无法使用@secured 或@preauthorize 注释访问端点。
LOGS IN CONSOLE(spring app):“未经授权的错误:访问此资源需要完全身份验证”。
使用 POSTMAN 可以正常工作,所以这是前端的问题。
角度:
_helper
import { HTTP_INTERCEPTORS, HttpEvent } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { HttpInterceptor, HttpHandler, HttpRequest } from '@angular/common/http';
import { TokenStorageService } from '../_services/token-storage.service';
import { Observable } from 'rxjs';
const TOKEN_HEADER_KEY = 'Authorization'; // for Spring Boot back-end
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
constructor(private token: TokenStorageService) { }
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
let authReq = req;
const token = this.token.getToken();
if (token != null) {
authReq = req.clone({ headers: req.headers.set(TOKEN_HEADER_KEY, 'Bearer ' + token) });
}
return next.handle(authReq);
}
}
export const authInterceptorProviders = [
{ provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true }
];
_services
import { Injectable } from '@angular/core';
const TOKEN_KEY = 'auth-token';
const USER_KEY = 'auth-user';
@Injectable({
providedIn: 'root'
})
export class TokenStorageService {
constructor() { }
signOut(): void {
window.sessionStorage.clear();
}
public saveToken(token: string): void {
window.sessionStorage.removeItem(TOKEN_KEY);
window.sessionStorage.setItem(TOKEN_KEY, token);
}
public getToken(): string | null {
return window.sessionStorage.getItem(TOKEN_KEY)
}
public saveUser(user: any): void {
window.sessionStorage.removeItem(USER_KEY);
window.sessionStorage.setItem(USER_KEY, JSON.stringify(user));
}
public getUser(): any {
const user = window.sessionStorage.getItem(USER_KEY);
if (user) {
return JSON.parse(user);
}
return {};
}
}
组件示例(针对用户)
import { Component, OnInit } from '@angular/core';
import { AuthService } from '../_services/auth.service';
import { TokenStorageService } from '../_services/token-storage.service';
@Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit {
form: any = {
username: null,
password: null
};
isLoggedIn = false;
isLoginFailed = false;
errorMessage = '';
roles: string[] = [];
constructor(private authService: AuthService, private tokenStorage: TokenStorageService) { }
ngOnInit(): void {
if (this.tokenStorage.getToken()) {
this.isLoggedIn = true;
this.roles = this.tokenStorage.getUser().roles;
}
}
onSubmit(): void {
const { username, password } = this.form;
this.authService.login(username, password).subscribe(
data => {
this.tokenStorage.saveToken(data.token); //token
this.tokenStorage.saveUser(data);
this.isLoginFailed = false;
this.isLoggedIn = true;
this.roles = this.tokenStorage.getUser().roles;
this.reloadPage();
},
err => {
this.errorMessage = err.error.message;
this.isLoginFailed = true;
}
);
}
reloadPage(): void {
window.location.reload();
}
}
更新: 在调试器中运行 spring 应用程序后,我得到了这个: ((UsernamePasswordAuthenticationToken)authentication).authorities = 找不到局部变量'authentication'
spring boot 应用中有 AuthJwt 代码:
@Override
public void commence(HttpServletRequest request, HttpServletResponse response,
AuthenticationException authException) throws IOException {
logger.error("Unauthorized error: {}", authException.getMessage());
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Error: Unauthorized");
}
【问题讨论】:
-
const token = this.token.getToken(); debugger; if (token != null) { authReq = req.clone({ headers: req.headers.set(TOKEN_HEADER_KEY, 'Bearer ' + token) });}在那里放置一个调试器标签并检查拦截器克隆和修改的请求中的内容 -
我不知道为什么,但它没有抓住这一点,就好像它从未发生过一样
-
您是否将
AuthInterceptor添加为AppModule的提供者?也许将您的AppModule添加到问题中。我认为还需要将HttpClientModule和BrowserModule导入到@NgModule -
所以...我确实忘记了,非常感谢!现在它可以工作了:)
-
您介意我将其添加为答案并且您接受它以帮助未来的用户吗?
标签: angular spring-security jwt authorization