前后端分离下用jwt做用户认证

数字先锋
• 阅读 8537

0 前后端分离下的用户信息认证

前端使用Vue+axios,后端使用SpringBoot+SpringSecurity。

为了解决http无状态的问题,我采用jwt(json web token)保存用户信息,前端每次发起请求时带上,交给后端做用户认证。此时需要解决的问题是后端如何将生成的jwt返回前端,以及前端在拿到jwt后如何在每次请求时携带jwt。

1 后端校验用户成功以后,将生成的token写到响应头里

response.addHeader("Authorization", "Bearer " + jwt);

jwt就是自己生成的token,是String类型。

<!-- jwt依赖 -->
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.0</version>
</dependency>
// 完整代码

/**
 * 登录验证
 * 登录成功就生成token并放入响应头
 */
public class JwtLoginFilter extends UsernamePasswordAuthenticationFilter {

    private AuthenticationManager authenticationManager;

    public JwtLoginFilter(AuthenticationManager authenticationManager) {
        this.authenticationManager = authenticationManager;
    }

    private static final Logger logger
            = LoggerFactory.getLogger(JwtLoginFilter.class);

    // 省略了重写的attemptAuthentication()
    
    @Override
    protected void successfulAuthentication(HttpServletRequest request,
                                            HttpServletResponse response,
                                            FilterChain chain,
                                            Authentication authResult)
            throws IOException, ServletException {
        // 获取用户角色
        Collection<? extends GrantedAuthority> authorities = authResult.getAuthorities();
        // 我的数据库设计了一个用户只会有一个角色
        Iterator<? extends GrantedAuthority> iterator = authorities.iterator();
        String role = "";
        if (iterator.hasNext()) {
            role = iterator.next().getAuthority();
        }

        // 生成token
        String jwt = Jwts.builder()
                //配置用户角色
                .claim("authorities", role)
                .setSubject(authResult.getName())
                //过期时间,一小时
                .setExpiration(new Date(System.currentTimeMillis() + 60 * 60 * 1000))
                .signWith(SignatureAlgorithm.HS512, "密钥")
                .compact();

        //将token写到响应头里
        response.addHeader("Authorization", "Bearer " + jwt);
        // 自定义方法,给响应设置状态码等
        ResponseDataUtil.setDataInResponse(response,
                null,
                HttpStatusEnum.SUCCESSFUL,
                true);
    }
}

2 后端开启配置,使前端可以获取到响应头里的token

/**
 * 配置cors,解决前端访问后端的跨域资源问题
 */
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                //设置了前端的地址
                .allowedOrigins("http://localhost:10011")
                .allowedMethods("GET", "POST", "DELETE", "PUT", "OPTIONS", "HEAD")
                .allowedHeaders("*")
                //将请求头里保存的token暴露出来给前端获取
                .exposedHeaders("Authorization");
    }
}

重点是调用了exposedHeaders(),否则前端无法获取到响应头中键为Authorization的值。

现在,登录请求的响应头中已经增加了保存着token的Authorization。

前后端分离下用jwt做用户认证

3 前端在登录方法的回调函数里面获取响应头里的token

login() {
      // 对表单数据的有效性进行验证
      this.$refs.loginFormRef.validate(async valid => {
        if (!valid) return
        // 表单数据有效,发送请求
        const data = await this.$request.postWithBody('login', this.loginForm)
        if (data.successful) {
          // 将token保存到本地
          window.sessionStorage.setItem('jwt', data.token)
          this.$router.push('/home')
        }
      })
    }

this.$request.postWithBody('login', this.loginForm)是我自己封装的axios方法,用于发送post请求。当然完全可以用原生额axios的post方法。

window.sessionStorage.setItem('jwt', data.token)将从后台返回的token保存在本地。其中jwt是这个键值对的键,可以根据自己的习惯命名。

4 前端axios配置请求拦截器,给每个请求加上token

// 请求拦截器
axios.interceptors.request.use(request => {
  // 显示进度条
  Nprogress.start()
  request.headers.Authorization = window.sessionStorage.getItem('jwt')
  return request
})

这一步可以将前端发送的每一个请求都拦截下来,并在请求头里添上第3步中获取到的jwt。

5 效果

前后端分离下用jwt做用户认证

此时,前端发送的请求中,已经在请求头加入了jwt,后端收到请求后,将请求头里的token取出进行解析,完成用户认证。

本文由博客群发一文多发等运营工具平台 OpenWrite 发布
点赞
收藏
评论区
推荐文章
Wesley13 Wesley13
3年前
java将前端的json数组字符串转换为列表
记录下在前端通过ajax提交了一个json数组的字符串,在后端如何转换为列表。前端数据转化与请求varcontracts{id:'1',name:'yanggb合同1'},{id:'2',name:'yanggb合同2'},{id:'3',name:'yang
Easter79 Easter79
3年前
springboot2之优雅处理返回值
前言最近项目组有个老项目要进行前后端分离改造,应前端同学的要求,其后端提供的返回值格式需形如{"status":0,"message":"success","data":{}}方便前端数据处理。要实现前端同学这个需求,其实也挺简单的,
kenx kenx
3年前
Java MD5和SHA256等常用加密算法
前言我们在做java项目开发的时候,在前后端接口分离模式下,接口信息需要加密处理,做签名认证,还有在用户登录信息密码等也都需要数据加密。信息加密是现在几乎所有项目都需要用到的技术,身份认证、单点登陆、信息通讯、支付交易等场景中经常会需要用到加密算法,所谓加密算法,就是将原本的明文通过一系列算法操作变成密文。1.BASE严格地说,属于编码格式,而非加密算法
Chase620 Chase620
4年前
前端异常监控解决方案研究 – 腾讯CDC
前端监控包括行为监控、异常监控、性能监控等,本文主要讨论异常监控。对于前端而言,和后端处于同一个监控系统中,前端有自己的监控方案,后端也有自己等监控方案,但两者并不分离,因为一个用户在操作应用过程中如果出现异常,有可能是前端引起,也有可能是后端引起,需要有一个机制,将前后端串联起来,使监控本身统一于监控系统。因此,即使只讨论前端异常监控,其实也不能严格区分前
Stella981 Stella981
3年前
Go + Gin + Vue打包成一个文件
介绍为方便部署,在开发时,可以是前后端分离的,但进行部署的时候,在某些领域前后端分离部署显得多此一举,为了让部署变得简单,所以需要考虑是否可以将前端与后端在生产时直接生成为一个文件所需工具https://github.com/gobindata/gobindatahttps://github.com/elaz
Stella981 Stella981
3年前
Kerberos无约束委派的攻击和防御
 0x00前言简介当ActiveDirectory首次与Windows2000Server一起发布时,Microsoft就提供了一种简单的机制来支持用户通过Kerberos对Web服务器进行身份验证并需要授权用户更新后端数据库服务器上的记录的方案。这通常被称为Kerberosdoublehopissue(双跃点问题),
Stella981 Stella981
3年前
AJAX学习笔记(五、AJAX+JSON与Servlet前后端交互)
前后端分离实现前后端分离的好处就不用多说了,前后端那么JavaWeb项目前后端分离是怎么实现的呢?1.浏览器发送请求2.直接到达html页面(前端控制路由与渲染页面,整个项目开发的权重前移)3.html页面负责调用服务端接口产生数据(通过ajax等等,后台返回json格式数据,json数据格式因为简洁高效而取代xml)
Stella981 Stella981
3年前
ASP.NET Core 奇技淫巧之接口代理转发
前言先讲讲本文的开发背景吧..在如今前后端分离的大背景下,咱的客户又有要求啦~要前后端分离~然因为种种原因..没办法用用纯前端的框架(其实是学习成本高,又没钱请前端开发人员)...所以最终决定了一种方案..那就是采用MVC(只处理前端视图层,单纯是为了托管在.netcore上)Webapi的方式来实现前后端分离(讲真,很奇葩)..
Stella981 Stella981
3年前
Django REST framework JWT学习
1.JWT学习在用户注册或登录后,我们想记录用户的登录状态,或者为用户创建身份认证的凭证。我们不再使用Session认证机制,而使用JsonWebToken认证机制。Jsonwebtoken(JWT),是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC7519).该token被设计为紧凑且安全的,
孟达 孟达
1年前
分享一款JAVA开发的,非常棒的开源ERP系统
本系统包含销售、研发BOM、采购、生产计划、车间、仓库、应收应收付等模块。适用于传统制造业中小企业使用,适合进行二次开发和定制型开发。国内技术领先的ERP系统,采用前后端分离的模式,可切换为微服务版本。后端采用SpringBoot、SpringCloud、Jwt。前端采用Vue、Elementui,权限认证使用Redis。
美凌格栋栋酱 美凌格栋栋酱
5个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(