Spring Boot Angular 登录错误“ERR_TOO_MANY_REDIRECTS”

Posted

技术标签:

【中文标题】Spring Boot Angular 登录错误“ERR_TOO_MANY_REDIRECTS”【英文标题】:Spring boot Angular Login Error " ERR_TOO_MANY_REDIRECTS" 【发布时间】:2021-08-24 07:47:44 【问题描述】:

我想使用 Spring Boot 和 Angular 登录,但我得到“ERR_TOO_MANY_REDIRECTS”行。在后端,有一个返回令牌、用户名、密码和角色的响应。后端部分与邮递员合作,我没有得到同样的错误。相关代码如下。我的错误是什么?谢谢。

HttpInterceptorService

import  HttpInterceptor, HttpRequest, HttpHandler, HttpEvent, HttpHeaders, HTTP_INTERCEPTORS  from '@angular/common/http';
import  Injectable  from '@angular/core';
import  Observable, throwError  from 'rxjs';
import  AuthenticationService  from './services/authentication.service';
import  catchError  from 'rxjs/operators';


@Injectable()
export class HttpInterceptorService implements HttpInterceptor 

    constructor(private authenticationService: AuthenticationService)  

    intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> 

        const currentUser = this.authenticationService.currentUserValue;
        if (currentUser && currentUser.generateToken) 
            request = request.clone(
                setHeaders: 
                    Authorization: `Basic $currentUser.generateToken`
                
            );
        

        return next.handle(request);
    



AuthenticationService


import  HttpClient, HttpHeaders  from '@angular/common/http';
import  Injectable  from '@angular/core';
import  map  from 'rxjs/operators';
import  Router  from '@angular/router';
import  environment  from 'src/environments/environment';
import  Observable, BehaviorSubject  from 'rxjs';
import  KullaniciKariyer  from '../models/cvModel/KulaniciKariyer';
import  JwtResponse  from '../models/JwtResponse';

const apiHost = environment.host;

const httpOptions = 
  headers: new HttpHeaders( 'Content-Type': 'application/json' )
;

@Injectable(
  providedIn: 'root'
)
export class AuthenticationService 

  public username: String;
  public password: String;

  public currentUser: Observable<JwtResponse>;
  private currentUserSubject: BehaviorSubject<JwtResponse>;

  constructor(private http: HttpClient) 
    this.currentUserSubject = new BehaviorSubject<JwtResponse>(JSON.parse(localStorage.getItem('currentUser')));
    this.currentUser = this.currentUserSubject.asObservable();
  

  public get currentUserValue(): JwtResponse 
    return this.currentUserSubject.value;
  

  login(tcKimlikNo: string, password: string): Observable<any> 
  
    return this.http.get<any>(apiHost + '/api/login').pipe(
      map(response => 
        if (response) 
          localStorage.setItem('currentUser', JSON.stringify(response));
          this.currentUserSubject.next(response);
        
        return response;
      )
    );
  

  logout() 
    localStorage.removeItem('currentUser');
    this.currentUserSubject.next(null);
  




export class JwtResponse 
    generateToken: string;
    username: string;
    password: string;
    roles: string[] = [];



Guard  

import  CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router  from "@angular/router";
import  Injectable  from "@angular/core";
import  AuthenticationService  from 'src/app/services/authentication.service';
import  KullaniciKariyer  from 'src/app/models/cvModel/KulaniciKariyer';
import  JwtResponse  from 'src/app/models/JwtResponse';

@Injectable()
export class LoginGuard implements CanActivate 


  currentUser: JwtResponse;

  constructor(private router: Router,
    private authenticationService: AuthenticationService)  
  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) 

    const currentUser = this.authenticationService.currentUserValue;
    if (currentUser) 
      // logged in so return true
      return true;
    

    // not logged in so redirect to login page with the return url
    this.router.navigate(["anasayfa"]);
    return false;
  




Login.componenet

onSubmit() 

    this.authenticationService.login(this.loginForm.value.username, this.loginForm.value.password)
      .subscribe(
        data => 
          
            this.invalidLogin = false;
            this.loginSuccess = true;
            this.successMessage = 'Success.';
            this.authenticationService.isAuthenticationFunc(true);
            sessionStorage.setItem('role', data.roles);
            this.router.navigate(['pages']);

        ,
        error => 
          this.errorMessage = error.message;;
          this.loading = false;
        );
   
  



Pages.Routing

const routes: Routes = [
  
    path: '',
    component: PagesComponent,
    children: [
      
      
        path: 'admin',
        loadChildren: () => import('./admin/admin.module').then(m => m.AdminModule),
        canActivate: [LoginGuard]
      ,

      
        path: 'editor',
        loadChildren: () => import('./editor/editor.module').then(m => m.EditorModule),
        canActivate: [LoginGuard]
      
    ],
  
];


AdminRouting.Routing

@NgModule(
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule],
)
export class PagesRoutingModule  


const routes: Routes = [
  
    path: 'userCreate',
    component: UserCreateComponent,
    canActivate: [LoginGuard],
    data:  roles: [Constants.ROLE_ADMIN] 
  
];

@NgModule(
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule],
)
export class AdminRoutingModule  


EditorRouting.Routing

@NgModule(
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule],
)
export class PagesRoutingModule  


const routes: Routes = [
  
    path: 'userList',
    component: UserListComponent,
    canActivate: [LoginGuard],
    data:  roles: [Constants.ROLE_EDITOR] 
  
];

@NgModule(
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule],
)
export class EditorRoutingModule  

后台

WebSecuritConfig

    @Configuration
    @EnableWebSecurity
    @EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
    public class WebSecurityConfig extends WebSecurityConfigurerAdapter 
    
        @Autowired
        UserServiceImpl userServiceImpl;
    
        @Autowired
        private JwtTokenUtil jwtTokenUtil;
    
        @Bean
        @Override
        public AuthenticationManager authenticationManagerBean() throws Exception 
            return super.authenticationManagerBean();
        
    
        @Override
        public void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception 
            authenticationManagerBuilder.userDetailsService(userServiceImpl).passwordEncoder(passwordEncoder());
        
    
        @Bean
        public PasswordEncoder passwordEncoder() 
            return new BCryptPasswordEncoder();
        
    
        @Override
        protected void configure(HttpSecurity http) throws Exception 
            http.cors().and().csrf().disable().
                    authorizeRequests()
                    .antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
                    .anyRequest().fullyAuthenticated()
                    .and()
                    .formLogin().loginPage("/api/login")
                    .and()
                    .httpBasic();
    
            http.addFilter(new JwtAuthorizationFilter(authenticationManager(), jwtTokenUtil));
    
        
    
        @Bean
        public WebMvcConfigurer corsConfigurer() 
            return new WebMvcConfigurer() 
                @Override
                public void addCorsMappings(CorsRegistry registry) 
                    registry.addMapping("/**").allowedOrigins("*").allowedMethods("*");
                
            ;
        
    
    
    ********************
    
    @Service
    @Transactional
    public class UserServiceImpl implements UserDetailsService 
    
        @Autowired
        private UserRepository userRepository;
    
        @Override
        public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException 
    
            User user = userRepository.findByuserName(userName);
    
            if (user == null) 
                throw new UsernameNotFoundException("User Name is not Found");
            
    
            return new org.springframework.security.core.userdetails.User(user.getuserName(), user.getPassword(), getAuthority(user));
    
        
    
        public List<SimpleGrantedAuthority> getAuthority(User user) 
    
            List<SimpleGrantedAuthority> authorities = user.getRoles().stream()
                    .map(role -> new SimpleGrantedAuthority(role.getRoleAdi()))
                    .collect(Collectors.toList());
    
            return authorities;
        
    
    


@GetMapping("/api/login")
        public ResponseEntity<?> login(Principal principal) 
            if (principal == null) 
                return ResponseEntity.ok(principal);
            
            UsernamePasswordAuthenticationToken authenticationToken = (UsernamePasswordAuthenticationToken) principal;
            User user = userRepository.findByUsername(authenticationToken.getName());
    
            
            List<String> roles = user.getRoles().stream()
                    .map(role -> role.getRoleName())
                    .collect(Collectors.toList());
    
            return ResponseEntity.ok(new JwtResponse(jwtTokenUtil.generateToken(authenticationToken),
                    user.getUserName(),
                    user.getPassword(),
                    roles));
        

【问题讨论】:

你在使用formLogin吗?你能分享一下你的 springboot 应用的 websecurity 配置吗? 我再次编辑并添加了代码。 【参考方案1】:

您收到太多重定向,因为您使用登录页面/api/login/ 的spring security,但不允许在配置中使用它。所以spring security会自动重定向到登录页面,但即使登录页面也需要身份验证,所以重定向会一次又一次地发生。您可以通过在 formLogin 块末尾添加 permitAll() 方法来解决此问题。

   .formLogin()
      .loginPage("/api/login")
      .permitAll();

但理想情况下,您不应该使用formlogin().loginPage() 的 javadoc 是这样说的:

login page to redirect to if authentication is required

此登录页面需要在/api/login 使用请求正文中的用户名和密码发出POST 请求。完成后,您将被重定向到其他页面。由于您使用的是 Angular,因此您需要一个登录 api。

您可以查看different ways to achieve angular login with springboot

此外,您也没有通过角度形式传递用户凭据。

【讨论】:

以上是关于Spring Boot Angular 登录错误“ERR_TOO_MANY_REDIRECTS”的主要内容,如果未能解决你的问题,请参考以下文章

whitelabel 错误页面 404 spring boot angular 5

spring boot angular 2 post方法403错误

将 Angular 与 JWT 的 Spring Boot 连接时出现 CORS 错误

Angular 4.0 + Spring boot + Spring Security:TemplateInputException:解析模板“登录”时出错

如何使用 Angular 和 Spring Boot 添加社交登录功能

如何使用spring boot和angular 2登录