SpringBoot+Angular JWT角色认证报错求助
基于JWT和角色权限的认证功能开发报错排查请求
我正在开发基于JWT和角色权限的认证功能,目前遇到错误导致登录流程无法正常执行,问题出在LoginComponent中被注释的代码行。这是我首次使用JWT和角色权限实现认证,尝试多次仍无法解决,恳请协助排查。
Angular端代码
AgentService
import { HttpClient, HttpHeaders } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { AgentAuthenService } from './agent-authen.service'; import { tap } from 'rxjs'; @Injectable({ providedIn: 'root' }) export class AgentService { private readonly path="http://localhost:9090"; constructor(private httpclient: HttpClient, private agentAuthenServ:AgentAuthenService) { } public login(mat: string, password: string){ const url = `${this.path}/authentication`; const headers ={'Content-Type': 'application/json'}; const body ={mat,password}; return this.httpclient.post<any>(url,body,{headers}).pipe(tap(response =>{ const token = response.token; const roles = response.agent.role; this.agentAuthenServ.setToken(token); this.agentAuthenServ.setToken(roles); })); } }
AgentAuthenService
import { Injectable } from '@angular/core'; @Injectable({ providedIn: 'root' }) export class AgentAuthenService { constructor() { } public setToken(token:string){ localStorage.setItem("token",token); } public getToken():string{ return localStorage.getItem("token"); } public setRole(role:[]){ localStorage.setItem("role", JSON.stringify(role)); } public getRole(): string[] { return JSON.parse(localStorage.getItem("role")); } public clearStorge(){ localStorage.clear(); } public logged(){ return this.getRole() && this.getToken(); } }
LoginComponent(问题出在注释的代码行)
import { Component, OnInit } from '@angular/core'; import { NgForm } from '@angular/forms'; import { Router } from '@angular/router'; import { AgentService } from '../_services/agent.service'; import { AgentAuthenService } from '../_services/agent-authen.service'; @Component({ selector: 'app-login', templateUrl: './login.component.html', styleUrls: ['./login.component.css'] }) export class LoginComponent implements OnInit { constructor(private agentSer: AgentService, private agentAuthenSer: AgentAuthenService, private router: Router){} ngOnInit():void{} connect(loginF:NgForm){ const agentPassword=loginF.value.agentPassword; const agentMat= loginF.value.agentMat //this.agentSer.login(agentPassword,agentMat).subscribe( (response:any) =>{ const role = response.agent.role[0]; this.agentAuthenSer.setRole(response.agent.role); this.agentAuthenSer.setToken(response.jwtToken); console.log(response); if(role=== 'ChargeClient'){ this.router.navigate(['accueil/charge']); }else{ if(role=== 'AnalysteCredit'){ this.router.navigate(['accueil/analyste']);} else{ if (role=== 'ChefAgence'){ this.router.navigate(['accueil/chefA']); }else{ this.router.navigate(['accueil/chefZ']); }}}} ); } }
SpringBoot端代码
WebSecurity配置
package com.example.banque.configuration; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpHeaders; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; @Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true) public class WebSec extends WebSecurityConfigurerAdapter { @Autowired private JwtAuthenticationEntry jwtAuthenticationEntry; @Autowired private JwtRequestFilter jwtRequestFilter; @Bean @Override public AuthenticationManager authenticationManagerBean() throws Exception{ return super.authenticationManagerBean(); } @Override protected void configure(HttpSecurity httpSecurity) throws Exception{ httpSecurity.cors(); httpSecurity.csrf().disable().authorizeHttpRequests() .antMatchers("/authentication").permitAll() .antMatchers(HttpHeaders.ALLOW).permitAll() .anyRequest().authenticated() .and() .exceptionHandling().authenticationEntryPoint(jwtAuthenticationEntry) .and() .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); httpSecurity.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class); } }
JwtRequestFilter
package com.example.banque.configuration; import com.example.banque.service.JwtService; import com.example.banque.utils.JwtUtil; import io.jsonwebtoken.ExpiredJwtException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.web.authentication.WebAuthenticationDetails; import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; import org.springframework.stereotype.Component; import org.springframework.web.filter.OncePerRequestFilter; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @Component public class JwtRequestFilter extends OncePerRequestFilter { @Autowired private JwtUtil jwtUtil; @Autowired private JwtService jwtService; @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { final String header =request.getHeader("Authorization"); String jwtToken=null; String agentMat=null; if (header != null && header.startsWith("Bearer ")){ jwtToken= header.substring(7); try{ agentMat=jwtUtil.getAgentMat(jwtToken); }catch(IllegalArgumentException e) { System.out.println("Ne peut pas récupérer le token"); }catch (ExpiredJwtException e){ System.out.println("Le token a expiré"); } }else{ System.out.println("Le token ne commence pas avec Bearer"); } if (agentMat != null && SecurityContextHolder.getContext().getAuthentication() == null){ UserDetails userDetails= jwtService.loadUserByUsername(agentMat); if (jwtUtil.validateToken(jwtToken, userDetails)){ UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken =new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities()); usernamePasswordAuthenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken); } } filterChain.doFilter(request,response); } }
JwtController
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.CrossOrigin; @RestController @CrossOrigin public class JwtController { @Autowired private JwtService jwtService; @PostMapping({"/authentication"}) public JwtResponse createJwtToken(@RequestBody JwtRequest jwtRequest) throws Exception{ return jwtService.createJwtToken(jwtRequest); } }
核心问题排查点
- AgentService方法调用错误:
login方法的tap操作中,this.agentAuthenServ.setToken(roles);应为this.agentAuthenServ.setRole(roles);,错误地用角色覆盖了token存储。 - LoginComponent参数顺序错误:
agentSer.login(agentPassword,agentMat)参数顺序颠倒,需改为agentSer.login(agentMat, agentPassword)(与AgentService的方法定义匹配)。 - 前后端返回字段不匹配:AgentService取
response.token,但LoginComponent取response.jwtToken,需统一与后端JwtResponse的字段名保持一致。 - AgentAuthenService空值处理缺失:
getToken()和getRole()未处理localStorage返回null的情况,会导致JSON.parse报错,需补充空值判断:public getToken(): string | null { return localStorage.getItem("token"); } public getRole(): string[] | null { const roleStr = localStorage.getItem("role"); return roleStr ? JSON.parse(roleStr) : null; } - JwtController注解导入缺失:原代码缺少
@CrossOrigin的导入语句,需补充import org.springframework.web.bind.annotation.CrossOrigin;。
内容的提问来源于stack exchange,提问作者ChirazBS
相关产品推荐
相关产品推荐

