首页 > 解决方案 > 使用 Spring Security 的客户端基于 cookie 的身份验证

问题描述

我们有一个完整的后端登录 POST 服务,使用 Spring Security 以及 Spring Boot 和 Spring Session 实现。用户需要登录才能访问其他服务。登录操作有效,限制/允许访问其他服务的机制也有效。这已经用 Postman 进行了测试,它“足够聪明”,可以将会话 cookie 保存在连续的请求中。

现在,我们正在尝试在 React 上构建客户端。使用浏览器的调试时,我们可以看到会话 cookie 在响应头中发送,没有问题。我们试图从标头中获取会话 cookie 并将其存储以供后续请求使用,但它不起作用。在调查时,我们了解到我们并不打算从代码中读取响应标头,正如这里这里所解释的那样。

我们的登录操作应该重定向到 /customer/home,它在 Postman 中有效,但在我们的应用程序中无效。我们得到的行为是 403 Forbidden,我们评估它的方式是因为重定向时没有设置 cookie,因此第二次操作(GET /customer/home)失败并返回 403。我们的理解是否正确?但是,浏览器似乎不会自动保留会话 cookie。如果 cookie 没有自动设置,我们应该如何维护后续请求的会话,并且我们不应该手动读取它?我们是否应该不为此目的使用 cookie,而是发布身份验证令牌?

我们显然误解或遗漏了一些东西。请问有什么指点吗?

我们的 WebSecurityConfigurerAdapter:

@EnableWebSecurity
@Configuration
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private AuthenticationProviderService authenticationProviderService;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                    .antMatchers("/customer/register").permitAll()
                    .anyRequest().fullyAuthenticated()
                    .and()
                .formLogin()
                    .permitAll()
                    .defaultSuccessUrl("/customer/home", false)
                    .and()
                .logout()
                    .permitAll()
                    .and()
                .httpBasic();
        http.csrf().disable();
    }
//[ . . . ]
}

我们的客户试图做一个 POST:

const mw = store => next => action => {

  if(action.type == 'SUBMIT_LOGIN_USER') {

    var payload = {
      username: action.user.username,
      password: action.user.password
    };

      // Build formData object.
    let formData = new FormData();
    formData.append('username', action.user.username);
    formData.append('password', action.user.password);


    return fetch('http://192.168.0.34:8080/login', {
      method: 'POST',
      body: formData
    }).then(
      r => (r)
    )
    .then(function(response) {
      console.log(document.cookie) //empty
      console.log(response.headers.get('Set-Cookie')) //null
      next(action)
    })
    .catch(function(err) {
      console.info(err);
    });
  } else {
    next(action)
  }
}

标签: reactjsrestcookiesloginspring-session

解决方案


使用 JWT(Jason Web Tokens)是在 React 等单页应用程序上实现安全性的好方法。

如果您使用 JWT 方法,那么使用 axios 之类的包来处理来自客户端的 http 请求会很有效。Axios 允许您轻松地将授权令牌添加到所有请求中,而无需麻烦。

即使您没有使用 JWT,也请尝试使用 axios 来有效地发送授权令牌。


推荐阅读