当前位置: 首页 > 知识库问答 >
问题:

Spring靴+Angular 2+JWT

扈韬
2023-03-14

我正在使用Angular 2,并试图在get方法上发送一个标头参数。我有以下代码:

let tokenUrl2 = "http://localhost:8080/users";

let headers = new Headers();
headers.append('abc', token);

let options = new RequestOptions({ headers: headers });
return this.http.get(tokenUrl2, options);

我得到这个错误:

Response for preflight is invalid (redirect)

我也添加了这些参数,但我得到了相同的错误:

headers.append('Content-Type', 'application/json');
headers.append('Authorization':'Bearer ' + token);

谁能告诉我什么是正确的方式发送头参数。非常感谢:)

URL“http://localhost:8080/users”来自spring boot web app(它是一个REST服务)。我正试图将angular应用程序与spring boot应用程序进行交流。我的想法是向它发送一个从另一个REST服务获得的令牌。在第一次Rest服务中,我得到了一个代币。这是一个与邮政的Rest服务,它的工作。然后,我通过GET方法将此令牌发送到第二个REST服务(http://localhost:8080/users)。这第二部分不起作用。我尝试将GET方法改为POST方法,因为在第一部分,使用POST方法可以工作,但这个新的更改都不起作用。我仍然得到同样的消息:预飞行响应无效(重定向)。

我有这些问题:

如果我的第一个REST服务(用POST实现)工作,为什么第二个不能呢?这是因为我的请求(我的angular应用程序)没有实现CORS?

我希望通过这些细节,你能帮助我解决我的问题。

编辑2

最初,我认为我只是在从Angular应用程序向REST服务发送headers参数时出错。但是,我已经调查过了,我发现我的问题包含了更多的成分。我讲述了我的组件:

我有一个角应用程序,需要从Spring boot应用程序消费一个REST服务。每个REST服务都需要身份验证,为此我使用JWT。

先。我的angular应用程序使用authenticate REST服务。如果这样做了。REST服务返回令牌。

其次。有了这个令牌,angular应用程序可以使用另一个使用Spring Security保护的REST服务。

我的错误发生在第二步。我不能消费别人的服务。我有一个从OncePerRequestFilter扩展而来的自定义筛选器,甚至不被调用。在angular应用程序中,我得到了一条我以前报告过的消息:

预飞行的响应无效(重定向)

public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {

    private final Log logger = LogFactory.getLog(this.getClass());

    @Autowired
    private UserDetailsService userDetailsService;

    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    @Value("${jwt.header}")
    private String tokenHeader;

    static final String ORIGIN = "Origin";

    @Override
    //@CrossOrigin(origins = "*")
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        // TODO Auto-generated method stub
        logger.info("checking authentication für user ");

        String authToken = request.getHeader(this.tokenHeader);

        // authToken.startsWith("Bearer ")
        // String authToken = header.substring(7);
        String username = jwtTokenUtil.getUsernameFromToken(authToken);

        if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {

            // It is not compelling necessary to load the use details from the database. You could also store the information
            // in the token and read it from it. It's up to you ;)
            UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);

            // For simple validation it is completely sufficient to just check the token integrity. You don't have to call
            // the database compellingly. Again it's up to you ;)
            if (jwtTokenUtil.validateToken(authToken, userDetails)) {
                UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
                authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                logger.info("authenticated user " + username + ", setting security context");
                SecurityContextHolder.getContext().setAuthentication(authentication);
            }
        }

        filterChain.doFilter(request, response);
    }
}
import { Component, OnInit } from '@angular/core';
import { LoginService } from './login.service';

interface TokenJson {
    token: string;
}


@Component({
    selector: 'login',
    templateUrl: 'login.component.html',
    styleUrls: ['login.scss'],
    providers: [LoginService]
})
export class LoginComponent implements OnInit {
    private model = {'username':'****', 'password':'****'};
    private currentToken:string ;
    private tokenJson: TokenJson;

    // constructor
    constructor(private _loginService: LoginService) {

    }

    // on-init
    ngOnInit() {
      debugger;
      this._loginService.sendCredential(this.model).subscribe(
         data => {
                   debugger;
                   //localStorage.setItem("token", JSON.parse(JSON.stringify(data)).token);

                  // this.currentToken = JSON.parse(JSON.stringify(data))._body;
                   this.tokenJson = JSON.parse(JSON.stringify(data))._body;

                   this.currentToken = JSON.parse(JSON.parse(JSON.stringify(data))._body).token;
                   localStorage.setItem("token",  this.currentToken);
                   this._loginService.sendToken(localStorage.getItem("token")).subscribe(
                     data => {
                               //this.currentUserName=this.model.username;
                               //localStorage.setItem("currentUserName", this.model.username);
                               debugger;
                               this.model.username='';
                               this.model.password='';
                             },
                     error => {
                       debugger;
                       console.log(error)
                     }
                   );
                 },
         error => {
           debugger;
           console.log(error)
         }
       );
    }


}

import {Injectable} from "@angular/core";
import {Http, Headers, Response, RequestOptions} from '@angular/http';
import {Observable}     from 'rxjs/Observable';


@Injectable()
export class LoginService {
  token: string;

  constructor (private http: Http) {}

  sendCredential(model) {
    debugger;

    let tokenUrl1 = "http://localhost:8080/auth";
    let headers = new Headers();
    headers.append('Content-Type', 'application/json');
    return this.http.post(tokenUrl1, JSON.stringify(model), {headers: headers});
  }

  sendToken(token) {
    debugger;
    let tokenUrl2 = "http://localhost:8080/users";
    console.log('Bearer '+token);


    let getHeaders2 = new Headers();
    getHeaders2.append('Authorization', token);

    let headers = new Headers();

    headers.append('authorization', token);



    return this.http.post(tokenUrl2, {}, options);
  }



}
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    //
    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers(HttpMethod.OPTIONS, "/**");
    }
    //

}

共有1个答案

沈博达
2023-03-14
 Response for preflight is invalid (redirect)

你在用CORS吗?(例如,您是否使用ng serve运行Angular应用程序,但试图访问不同端口/机器上的服务器?)。

 类似资料:
  • 我正在用Thymeleaf构建一个Spring Boot应用程序。我的模板(视图)和静态文件夹都在src/main/Resources/静态和src/main/Resources/tem板下。当我通过main方法(使用eclipse)运行应用程序时,一切都很好。但是,我已经按照说明创建了一个war文件,当我将其部署到Tomcat 7时——静态内容丢失了,只显示了Thymeleaf html模板。

  • angular 2+ Spring Boot Integration This example shows how to do a paginated table with Angular and Spring Boot (RestController ) Installation The Back End You'll need Maven 3+ and Java 8 The Front End

  • 作为一个新的Web应用程序项目的一部分,我计划学习Spring。我开始通读Spring框架参考。当我在谷歌上搜索时,我遇到了Spring boot。我所理解的是,Spring boot通过减少配置帮助构建应用程序的速度比Spring快得多。现在我有点困惑,我应该继续学习Spring还是跳转到Spring boot。我的目的是了解Spring作为一个框架是如何工作的,而不是一些特性。所以请让我知道,

  • 我正在使用Spring boot 2.0.2应用程序通过HTTPS对外部api进行REST api调用。 我是TLS和SSL的新手。我的理解是,TLS是一种更安全的方式,用于传输安全的敏感数据。 我的问题是: 如何确定我的应用程序使用的TLS版本

  • 我有两个项目。我用Angular2 cli构建的Angular2应用程序和只为Angular2应用程序服务的Spring Boot应用程序。我用构建Angular2应用程序,它会生成一个文件夹。然后,我将文件夹的内容放在Spring Boot应用程序的中。 我的Spring启动应用程序有两个文件。 Spring Boot应用程序类: 及其应用。属性文件: 它工作得很好,但是如果我转到一个url并点

  • 我正在练习使用spring boot来处理restful应用程序 我已经设置了@RestController和@Entity这样 和 当我用邮递员http://localhost:8080/cardatabase/api/cars我有一张汽车清单 但即使我去http://localhost:8081/cardatabase/cars,顶部嵌入 正常吗? 谢谢

  • 我在下面的链接中添加了过滤器作为问题的答案 Spring Boot Data Rest+CORS不能正确启用选项/删除

  • spring-boot-angular2 starter kit spring boot backend, angular2 frontend with webpack, typescript, sass, bootstrap4, karma, jasmine about a starter project for prototyping restful applications with spr