出处: https://www.cnblogs.com/zexin/p/10389541.html

我们平时自己开发项目,分布式的结构时,访问量不大,但是又不想搭建redis服务器,这时我觉得jwt不错.

个人理解,jwt就是类似于一把锁和钥匙,客户来租房(登录),我们需要给他进来(第一次登录)登记消息,配把钥匙给他(使用jwt生成一个token,存放在用的cookie中),

我们这边也需要配置一把我们需求的锁(jwt的生成token,解析token规则我们来写),接下来看下我最近运用jwt的小实例(该项目由springboot2.x搭建).

首先需要的maven工程pom.xml文件中添加依赖

<!-- JWT相关 -->
<dependency>
   <groupId>io.jsonwebtoken</groupId>
   <artifactId>jjwt</artifactId>
   <version>0.7.0</version>
</dependency>

自定义一个拦截类,用户没有钥匙的都需要登录(jwt生成的token)

/**
 * 自定义登录拦截器
 */
public class LoginIntercepter implements HandlerInterceptor {

    private static final Gson gson = new Gson();
    /**
     * 进入controller的拦截
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String token ="";
        //判断用户cookie中有无token
        Cookie[] ctoken = request.getCookies();
        if(ctoken!=null){
            for(Cookie ftoken: ctoken){
                if(ftoken.getName().equals("token")){
                    token = ftoken.getValue();
                }
            }
        }
        if (!token.isEmpty()){
            //3.如果用户有token,则进行jwt解密
            Claims claims = JWTUtils.checkToken(token);
            if (claims != null){
                //4.不为空,则说明用户已登录,获取用户id,姓名,保存在request中的Attribute作用域中,这样controller就可以取到值
                String signatureFile = (String) claims.get("signatureFile");
                String email = (String) claims.get("email");
                request.setAttribute("user_signatureFile",signatureFile);
                request.setAttribute("user_email",email);
                //5.放行
                return true;
            }
        }

        //6.返回错误信息给前端
        //sendMessage(response, JsonData.buildError("请登录"));
        //response.flushBuffer();
        response.sendRedirect("sign_in.html");
        return false;
    }

    /**
     * 发送错误信息给前端
     */
    public static void sendMessage(HttpServletResponse response, Object obj) throws IOException {
            response.setContentType("application/json;charset:utf-8");
            PrintWriter writer = response.getWriter();
            writer.print(gson.toJson(obj));
            writer.close();
            //需要刷新一下,怕有缓存
            response.flushBuffer();
    }
}

springboot中需要配置一个配置类,注册我们的自定义配置类

/**
 *自定义拦截类的配置类
 */
@Configuration
public class InterceptConfig implements WebMvcConfigurer {
    //注册一个我们登录的拦截类
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //我们需要排除登录,和注册的拦截(特别注意,我们还需要取消拦截静态资源的访问)
        String[] exclude = new String[]{"/sign_in.html","/sign_up.html","/static/**","/assets/**","/login","/user_register"};
        //1.需要对我们自定义的拦截器进行注册
        registry.addInterceptor(new LoginIntercepter()).addPathPatterns("/**").excludePathPatterns(exclude);//拦截路径
        WebMvcConfigurer.super.addInterceptors(registry);
    }
}

前面我们拦截类写好了,用户被拦截后会跳转到登录或者注册界面,这时,在我们的控制类中,我们需要根据表单提交的信息,生成相应的token,下面是控制类的重要代码,里面用到的JWTUtils下面会贴出来,方便大家复制

int save = userService.save(user);
if (save == 1) {
    //return JsonData.buildSuccess(user,"注册成功");
    //使用jwt来将用户信息生成token的字符串
    String token = JWTUtils.geneToken(user);
    //将token保存到cookie中去,并且设置时间为半个钟
    Cookie cookie  = new Cookie("token",token);
    cookie.setMaxAge(60*30);
    response.addCookie(cookie);
    response.sendRedirect("/index");
    //return  JsonData.buildError("注册成功,即将跳转到首页!",0);
 } else {
    return new JsonData(-1,null,"注册失败,请重试");
 }

用户登录后,cookie中会被保存我们jwt生成的token,我这里设置半个钟有效期,在上面的自定义拦截器中,用户访问页面,会先向用户拿取token,有token的话,会被解析出相应信息,并且直接跳入首页,无须登录.接下来下面是JWTUtils

public class JWTUtils {

    public static final String SUBJECT = "ouyan"; //编写发布者
    public static final int EXPIRE = 1000*60*60*30; //设置过期时间,单位为毫秒,过期时间为半个钟
    public static final String APPSECRET = "axin"; //设置密钥

    /**
     * 使用jwt生成token
     */
    public  static String geneToken(User user){
        //先判断是否为空,为空返回null
        if (user == null || user.getSignatureFile() == null || user.getEmail() == null ){
            return null;
        }
        String token = Jwts.builder().setSubject(SUBJECT).claim("signatureFile",user.getSignatureFile())
                .claim("email",user.getEmail()).setIssuedAt(new Date()).setExpiration(new Date(System.currentTimeMillis()+EXPIRE))
                .signWith(SignatureAlgorithm.HS256,APPSECRET).compact();
        return token;
    }

    /**
     * 校验密钥
     */
    public static Claims checkToken(String token) {
        try {
            final Claims claims = Jwts.parser().setSigningKey(APPSECRET)
                    .parseClaimsJws(token).getBody();
            return claims;
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("出错啦");
        }
            return null;

    }
}

使用JWT来实现单点登录功能的更多相关文章

  1. 如何使用JWT来实现单点登录功能

    我们平时自己开发项目,分布式的结构时,访问量不大,但是又不想搭建redis服务器,这时我觉得jwt不错. 个人理解,jwt就是类似于一把锁和钥匙,客户来租房(登录),我们需要给他进来(第一次登录)登记 ...

  2. Spring Security整合JWT,实现单点登录,So Easy~!

    前面整理过一篇 SpringBoot Security前后端分离,登录退出等返回json数据,也就是用Spring Security,基于SpringBoot2.1.4 RELEASE前后端分离的情况 ...

  3. 重学 Java 设计模式:实战装饰器模式(SSO单点登录功能扩展,增加拦截用户访问方法范围场景)

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 对于代码你有编程感觉吗 很多人写代码往往是没有编程感觉的,也就是除了可以把功能按照固 ...

  4. JWT&RSA实现单点登录(详细介绍)

    今天给大家讲一下基于JWT&RSA的单点登录(Single Sign On,简称SSO)解决方案 概念 首先要了解几个概念 单点登录(Single Sign On) JWT RSA 背景 为什 ...

  5. 看图理解JWT如何用于单点登录

    单点登录是我比较喜欢的一个技术解决方案,一方面他能够提高产品使用的便利性,另一方面他分离了各个应用都需要的登录服务,对性能以及工作量都有好处.自从上次研究过JWT如何应用于会话管理,加之以前的项目中也 ...

  6. 基于EasyNVR摄像机无插件直播流媒体服务器实现类似于单点登录功能的免登录直播功能

    提出问题 EasyNVR是一套摄像机无插件直播的流媒体服务器软件,他可以接入各种各样的摄像机,再经过转化统一输出无插件化直播的RTMP.HLS.HTTP-FLV流,同时,EasyNVR为了数据安全,提 ...

  7. 基于JWT机制的单点登录

    使用JWT实现单点登录时,需要注意token时效性.token是保存在客户端的令牌数据,如果永久有效,则有被劫持的可能.token在设计的时候,可以考虑一次性有效或一段时间内有效.如果设置有效时长,则 ...

  8. shiro中接入单点登录功能

    最近新建的系统中使用了shiro,而shiro框架中包含登录认证和鉴权的功能,因为我们系统要统一接入公司内部的单点登录(isso)系统,所以通过isso的登录用户,需要在shiro中置为已认证,一下提 ...

  9. jeecms框架单点登录功能的实现

    单点登录的功能实现主要原理: 1: 在点击登录按钮的时候使用reponse.addCookie()方法向浏览器发送cookie: 2: 在前段拦截器中的request.getCookie()在接收到设 ...

随机推荐

  1. javascript中把一个数组的内容全部赋值给另外一个数组

    如:var a = [1,2,3,4];var b= [];b = a;这个不是把值赋值过去而是b作为a的引用,b改变的是a如何b指向的是一个新数组,a把元素值全部赋值过去? 1.普通数组可以使用   ...

  2. NSString 对象保存在哪? @“xxx”和 stringWithFormat:@"xxx" 区别?

    NSString *str1=@"string";//这种是保存在常量池 NSString *str2=@"string"; NSLog(@"str1 ...

  3. 编写高质量代码改善C#程序的157个建议——建议30:使用LINQ取代集合中的比较器和迭代器

    建议30:使用LINQ取代集合中的比较器和迭代器 LINQ提供了类似于SQL的语法来实现遍历.筛选与投影集合的功能. static void Main(string[] args) { List< ...

  4. Java Thread.join()详解--父线程等待子线程结束后再结束

    目录(?)[+] 阅读目录 一.使用方式. 二.为什么要用join()方法 三.join方法的作用 join 四.用实例来理解 打印结果: 打印结果: 五.从源码看join()方法   join是Th ...

  5. 第一章:HTTP服务器,客户端简易代码解析

    HTTP服务器: 方法{ main service } service:读取HTTP请求信息    解析HTTP请求  决定HTTP相应正文的类型   创建HTTP相应结果  发送HTTP相应结果 读 ...

  6. Javascript脚本 : eval()函数

    Javascript 中 eval(X)函数 是将参数 当做语句来执行 var number1='1+2'; alert(number1); 输出为 '12': var number2=eval('1 ...

  7. php代码审计1(php.ini配置)

    1.php.ini基本配置-语法 大小写敏感directive = value(指令=值)foo=bar 不等于 FOO=bar 运算符| & - ! 空值的表达方法foo =     ;fo ...

  8. luoguP2982 [USACO10FEB]慢下来Slowing down

    https://www.luogu.org/problemnew/show/P2982 这题你写个树剖当然可以做,但是我们还有一种更简单的方法,使用 dfs 序 + 树状数组即可 考虑一只牛到了自己的 ...

  9. [原创]用WinRAR实现VC源代码快速压缩创建

    [原创]用WinRAR实现VC源代码快速压缩创建 by edata @ cnblogs.com/edata 2017-5-8 22:31:57 我们有的时候需要对vc项目压缩打包,因为vc项目的无关文 ...

  10. spark执行例子eclipse maven打包jar

    首先在eclipse Java EE中新建一个Maven project具体选项如下 点击Finish创建成功,接下来把默认的jdk1.5改成jdk1.8 然后编辑pom.xml加入spark-cor ...