从前端发送的授权令牌不起作用(JWT)
Posted
技术标签:
【中文标题】从前端发送的授权令牌不起作用(JWT)【英文标题】:Authorization token sent from frontend doesn't works (JWT) 【发布时间】: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
所以...我确实忘记了,非常感谢!现在它可以工作了:)
您介意我将其添加为答案并且您接受它以帮助未来的用户吗?
【参考方案1】:
确保AuthInterceptor
也在AppModule
中声明为提供者。
@NgModule(
providers: [authInterceptorProviders],
bootstrap: [AppComponent]
)
export class AppModule
【讨论】:
以上是关于从前端发送的授权令牌不起作用(JWT)的主要内容,如果未能解决你的问题,请参考以下文章
在 ASP .Net Core 2.2 中添加 JWT 令牌后授权不起作用
使用 OAuth2 保护服务,JWT 令牌不起作用 Spring Cloud
将 jwt 令牌添加到 GET 请求在 React 中不起作用
Spring Security JWT - 通过授权标头的邮递员身份验证有效,但从我的 Angular 前端不起作用