You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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);

    }
}

核心问题排查点

  1. AgentService方法调用错误:login方法的tap操作中,this.agentAuthenServ.setToken(roles);应为this.agentAuthenServ.setRole(roles);,错误地用角色覆盖了token存储。
  2. LoginComponent参数顺序错误:agentSer.login(agentPassword,agentMat)参数顺序颠倒,需改为agentSer.login(agentMat, agentPassword)(与AgentService的方法定义匹配)。
  3. 前后端返回字段不匹配:AgentService取response.token,但LoginComponent取response.jwtToken,需统一与后端JwtResponse的字段名保持一致。
  4. 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;
    }
    
  5. JwtController注解导入缺失:原代码缺少@CrossOrigin的导入语句,需补充import org.springframework.web.bind.annotation.CrossOrigin;。

内容的提问来源于stack exchange,提问作者ChirazBS

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 20:07:05