精华内容
下载资源
问答
  • token登录.rar

    2020-03-31 19:18:10
    拼多多登录便于刷单和店铺日常维护,免费体验,可导入多个小号,一键操作,方便快捷,安全稳定,更多功能自行挖掘。
  • 默认的,当我们关闭浏 览的时候,cookie会被删除。但可以通过修改cookie 的expire time使cookie在一定时间内有效 (3)OAuth OAuth(开放授权)是一个开放的授权标准,允许用户让第三方应用访问该用户在某一web...

    1.网页常用的几种验证方式

    (1)HTTP Basic Auth

    HTTP Basic Auth简单点说明就是每次请求API时都提供用户的username和password,简言之,Basic Auth是配合

    RESTful API 使用的最简单的认证方式,只需提供用户名密码即可,但由于有把用户名密码暴露给第三方客户端的

    风险,在生产环境下被使用的越来越少。因此,在开发对外开放的RESTful API时,尽量避免采用HTTP Basic Auth

    (2)Cookie Auth

    Cookie认证机制就是为一次请求认证在服务端创建一个Session对象,同时在客户端的浏览器端创建了一个Cookie

    对象;通过客户端带上来Cookie对象来与服务器端的session对象匹配来实现状态管理的。默认的,当我们关闭浏

    览器的时候,cookie会被删除。但可以通过修改cookie 的expire time使cookie在一定时间内有效

    (3)OAuth

    OAuth(开放授权)是一个开放的授权标准,允许用户让第三方应用访问该用户在某一web服务上存储的私密的资

    源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用。 OAuth允许用户提供一个令牌,而

    不是用户名和密码来访问他们存放在特定服务提供者的数据。每一个令牌授权一个特定的第三方系统(例如,视频

    编辑网站)在特定的时段(例如,接下来的2小时内)内访问特定的资源(例如仅仅是某一相册中的视频)。这样,

    OAuth让用户可以授权第三方网站访问他们存储在另外服务提供者的某些特定信息,而非所有内容这种基于OAuth的

    认证机制适用于个人消费者类的互联网产品,如社交类APP等应用,但是不太适合拥有自有认证

    权限管理的企业应用。

    (4)Token Auth

    使用基于 Token 的身份验证方法,在服务端不需要存储用户的登录记录。大概的流程是这样的:

    1. 客户端使用用户名跟密码请求登录

    2. 服务端收到请求,去验证用户名与密码

    3. 验证成功后,服务端会签发一个 Token,再把这个 Token 发送给客户端

    4. 客户端收到 Token 以后可以把它存储起来,比如放在 Cookie 里

    5. 客户端每次向服务端请求资源的时候需要带着服务端签发的 Token

    6. 服务端收到请求,然后去验证客户端请求里面带着的 Token,如果验证成功,就向客户端返回请求的数据

    Token Auth的优点

    支持跨域访问: Cookie是不允许垮域访问的,这一点对Token机制是不存在的,前提是传输的用户认证信息通

    过HTTP头传输.

    无状态(也称:服务端可扩展行):Token机制在服务端不需要存储session信息,因为Token 自身包含了所有登

    录用户的信息,只需要在客户端的cookie或本地介质存储状态信息.

    更适用CDN: 可以通过内容分发网络请求你服务端的所有资料(如:javascript,HTML,图片等),而你的服

    务端只要提供API即可.

    去耦: 不需要绑定到一个特定的身份验证方案。Token可以在任何地方生成,只要在你的API被调用的时候,你

    可以进行Token生成调用即可.

    更适用于移动应用: 当你的客户端是一个原生平台(iOS, Android,Windows 8等)时,Cookie是不被支持的

    (你需要通过Cookie容器进行处理),这时采用Token认证机制就会简单得多。

    CSRF:因为不再依赖于Cookie,所以你就不需要考虑对CSRF(跨站请求伪造)的防范。

    性能: 一次网络往返时间(通过数据库查询session信息)总比做一次HMACSHA256计算 的Token验证和解析

    要费时得多.

    不需要为登录页面做特殊处理: 如果你使用Protractor 做功能测试的时候,不再需要为登录页面做特殊处理.

    基于标准化:你的API可以采用标准化的 JSON Web Token (JWT). 这个标准已经存在多个后端库(.NET, Ruby,

    Java,Python, PHP)和多家公司的支持(如:Firebase,Google, Microsoft)

    2.什么是JWT

    JSON Web Token(JWT)是一个非常轻巧的规范。这个规范允许我们使用JWT在用户和服务器之间传递安全可靠的

    信息。在Java世界中通过JJWT实现JWT创建和验证。

    token的创建

    创建maven工程,引入依赖

    io.jsonwebtokenjjwt0.6.0

    创建类createJwtDemo,用于生成token

    packagecom.common.token;importio.jsonwebtoken.JwtBuilder;importio.jsonwebtoken.Jwts;importio.jsonwebtoken.SignatureAlgorithm;importjava.util.Date;public classcreateJwtDemo {/*** 通过jjwt创建token

    *@paramargs*/

    public static voidmain(String[] args) {

    JwtBuilder jwtBuilder= Jwts.builder().setId("id")

    .setSubject("赵") //用户信息

    .setIssuedAt(new Date()) //签名时间

    .signWith(SignatureAlgorithm.HS256, "bgyz")

    .claim("userId","123456")

    .claim("name","赵天")

    ;//设置签名防止被篡改

    /*** bgyz 注意最少4个字符,否则会报

    * Exception in thread "main" java.lang.IllegalArgumentException: secret key byte array cannot be null or empty.

    * 错误*/String token=jwtBuilder.compact();

    System.out.println(token);

    }

    }

    token的解析

    packagecom.common.token;importio.jsonwebtoken.Claims;importio.jsonwebtoken.Jwts;public classParseJwt {/*** 解析 jwtToken字符串

    *@paramargs*/

    public static voidmain(String[] args) {

    String token="eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiJpZCIsInN1YiI6Iui1tSIsImlhdCI6MTU4MDAyNjIxMiwidXNlcklkIjoiMTIzNDU2IiwibmFtZSI6Iui1teWkqSJ9.XFILGV-nflhhd_kO4df7aGcm_Z7ZRJ3gdx4HtU2Spfo";

    Claims claims= Jwts.parser().setSigningKey("bgyz").parseClaimsJws(token).getBody();//私有数据存放在 claims

    System.out.println(claims.getId());

    System.out.println(claims.getSubject());

    System.out.println(claims.getIssuedAt());/*** 解析自定义的claim中的内容*/System.out.println(claims.get("userId").toString());

    System.out.println(claims.get("name").toString());

    }

    }

    上面只是测试token,现在创建一个token验证的工具类

    packagecom.common.utils;importio.jsonwebtoken.Claims;importio.jsonwebtoken.JwtBuilder;importio.jsonwebtoken.Jwts;importio.jsonwebtoken.SignatureAlgorithm;importlombok.Getter;importlombok.Setter;importorg.springframework.beans.factory.annotation.Value;importorg.springframework.boot.context.properties.ConfigurationProperties;importjava.util.Date;importjava.util.Map;/*** 1.如果说,我们只是在某个业务逻辑中需要获取一下配置文件中的某个项值,使用@Value

    *

    * 2、如果说,我们专门编写了一个javaBean来和配置文件进行映射,我们就直接使用@ConfigurationProperties*/@Getter

    @Setter

    @ConfigurationProperties("jwt.config")public classJwtUtils {//签名私钥

    privateString key;//签名的失效时间//@Value("${jwt.config.ttl}")

    privateLong ttl;/*** 设置认证token

    * id:登录用户id

    * subject:登录用户名

    **/

    public String createJwt(String id,String name,Mapmap) {//1.设置失效时间

    long now = System.currentTimeMillis();//当前毫秒//System.out.println(ttl);

    long exp = now +ttl;//2.创建jwtBuilder

    JwtBuilder jwtBuilder =Jwts.builder().setId(id).setSubject(name)

    .setIssuedAt(newDate())

    .signWith(SignatureAlgorithm.HS256, key);//3.根据map设置claims

    for(Map.Entryentry : map.entrySet()) {

    jwtBuilder.claim(entry.getKey(),entry.getValue());

    }

    jwtBuilder.setExpiration(newDate(exp));//4.创建token

    String token =jwtBuilder.compact();returntoken;

    }/*** 解析token字符串获取clamis*/

    publicClaims parseJwt(String token) {

    Claims claims=Jwts.parser().setSigningKey(key).parseClaimsJws(token).getBody();returnclaims;

    }

    }

    View Code

    jwt.config 配置在 application.yml文件中

    jwt:

    config:

    key: bgyg

    ttl:50000

    springboot 启动类添加

    @BeanpublicJwtUtil jwtUtil(){return newutil.JwtUtil();

    }

    用户登录获取token和请求时携带token 后台解析token中的用户信息(写的简单例子,可以根据具体业务封装返回数据)

    packagecom.zhao.system.controller;importcom.common.utils.JwtUtils;importio.jsonwebtoken.Claims;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.util.StringUtils;import org.springframework.web.bind.annotation.*;importjavax.servlet.http.HttpServletRequest;importjava.util.HashMap;importjava.util.Map;

    @RestControllerpublic classusercontroller {

    @AutowiredprivateJwtUtils jwtUtils;/*** 使用jjwt token 进行验证登录*/@ResponseBody

    @GetMapping("/login")publicString login(){

    Map map= newHashMap();

    map.put("userName","张三");

    String token= jwtUtils.createJwt("1","zhao",map);returntoken;

    }

    ///*** 解析token 用get获取的 主要是测试*/// @ResponseBody

    // @GetMapping("/userInformation/{token}")

    //public String parseDemoToken(@PathVariable("token") String token){

    // Claims claims=jwtUtils.parseJwt(token);//claims.get("userName"); 获取设置的用户

    // return claims.get("userName").toString();

    // }/*** 解析token*/@ResponseBody

    @GetMapping("/userInformation")publicString parseToken(HttpServletRequest request){/*** 从请求头信息中获取token信息 token放在哪和前端约定就行了

    * 1.获取请求头 中的 名称=Authorization

    * 2.替换 Bearer +空格

    * 3.解析 token

    * 4.获取clamis

    **/String authorization= request.getHeader("Authorization");//spring 判断为空的方法

    if(StringUtils.isEmpty(authorization)){return "请进行登录";

    }//获取到token 信息

    String token = authorization.replace("Bearer", "");

    Claims claims=jwtUtils.parseJwt(token);//claims.get("userName"); 获取设置的用户

    return claims.get("userName").toString();

    }

    }

    展开全文
  • 最近做一个移动APP的项目,当用户登陆一段时间后从客户端请求服务器时需要验证用户身份,通常在web中的做法都是使用session或cooike来保持会话,但是放到手机端肯定是不合适的。我们使用qq或其他一些手机软件是都...

    最近做一个移动APP的项目,当用户登陆一段时间后从客户端请求服务器时需要验证用户身份,通常在web中的做法都是使用session或cooike来保持会话,但是放到手机端肯定是不合适的。我们使用qq或其他一些手机软件是都知道,登陆一次以后通常是不再需要再次登录的,这样如果使用session来实现也是可以的,但是如果把session的生命周期设为永久有效的话,对服务器端的资源消耗是非常大的。因此提出了使用token,首先说什么是token,翻译成中文就是“令牌”的意思。

    在Javaweb中servlet、Struts、sping都有token机制(令牌验证机制),但是在web项目中token的作用是用来防止表单重复提交,一般不是用来验证身份,而且,在web中token的值在每次跟服务器交互后都会发生变化,也就是说每次服务器都会生成一个新的token发送给客户端(浏览器)。如果是用来让移动端验证身份是很难实现的,但是我们可以使用token验证的思想,让服务器端为每个用户生成一个特定的字符串作为他们的“令牌”,服务器将这个字符串保存下来,当用户登陆一段时间后需要向服务器请求数据时带上这个标示即可,不必每次都验证用户名密码。生成这个字符串我使用的是用户名+密码+用户登录时间使用MD5加密,下面贴上MD5加密代码。

    用到的第三方包:commons-codec-1.8.jar

    Java

    import org.apache.commons.codec.digest.DigestUtils;

    /**

    * 创建日期:2015-1-5下午4:29:38

    * 作者:admin

    *TODO

    **/

    public class MD5_2 {

    public static void main(String[] args) {

    String str1 = DigestUtils.md5Hex("fghhfjgfhkghj");

    System.out.println(str1);

    System.out.println(str1.length());

     }

    }

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    importorg.apache.commons.codec.digest.DigestUtils;

    /**

    * 创建日期:2015-1-5下午4:29:38

    * 作者:admin

    *TODO

    **/

    publicclassMD5_2{

    publicstaticvoidmain(String[]args){

    Stringstr1=DigestUtils.md5Hex("fghhfjgfhkghj");

    System.out.println(str1);

    System.out.println(str1.length());

     }

    }

    喜欢 (5)or分享 (0)

    展开全文
  • 史上最全面的基于JWT token登陆验证

    千次阅读 2019-07-18 21:17:44
    1、什么是JWT:JWT(Json web token), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519)。 2、JWT的组成: jwt由header(头部),playload(载荷)、signature(签名三部分组成) 头部...

    介绍JWT

    1、什么是JWT:JWT(Json web token), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519)。
    2、JWT的组成
    jwt由header(头部),playload(载荷)、signature(签名三部分组成)
    头部部分header
    {
    “alg”: “HS256”,
    “typ”: “JWT”
    }
    alg描述的是签名算法。默认值是HS256。

    载荷部分payload
    {
    “iss”: “发行者”,
    “sub”: 主题”,
    “aud”: “观众”,
    “exp”:”过期时间”,
    “iat”:”签发时间”
    以下可以添加自定义数据
    “id”:”1”,
    “nickname”:”昵称”
    }

    签名部分signature
    HMACSHA256(Base64(Header) + “.” + Base64(Payload), secret),secret是加密的盐。
    签名的目的是用来验证头部和载荷是否被非法篡改。

    传统的session认证

    我们知道,http协议本身是一种无状态的协议,而这就意味着如果用户向我们的应用提供了用户名和密码来进行用户认证,那么下一次请求时,用户还要再一次进行用户认证才行,因为根据http协议,我们并不能知道是哪个用户发出的请求,所以为了让我们的应用能识别是哪个用户发出的请求,我们只能在服务器存储一份用户登录的信息,这份登录信息会在响应时传递给浏览器,告诉其保存为cookie,以便下次请求时发送给我们的应用,这样我们的应用就能识别请求来自哪个用户了,这就是传统的基于session认证。
    但是这种基于session的认证使应用本身很难得到扩展,随着不同客户端用户的增加,独立的服务器已无法承载更多的用户,而这时候基于session认证应用的问题就会暴露出来。

    基于session认证所显露的问题

    Session: 每个用户经过我们的应用认证之后,我们的应用都要在服务端做一次记录,以方便用户下次请求的鉴别,通常而言session都是保存在内存中,而随着认证用户的增多,服务端的开销会明显增大。

    扩展性: 用户认证之后,服务端做认证记录,如果认证的记录被保存在内存中的话,这意味着用户下次请求还必须要请求在这台服务器上,这样才能拿到授权的资源,这样在分布式的应用上,相应的限制了负载均衡器的能力。这也意味着限制了应用的扩展能力。

    CSRF: 因为是基于cookie来进行用户识别的, cookie如果被截获,用户就会很容易受到跨站请求伪造的攻击。

    基于token的鉴权机制

    基于token的鉴权机制类似于http协议也是无状态的,它不需要在服务端去保留用户的认证信息或者会话信息。这就意味着基于token认证机制的应用不需要去考虑用户在哪一台服务器登录了,这就为应用的扩展提供了便利。

    流程上是这样的:
    1、用户使用用户名密码来请求服务器
    2、服务器进行验证用户的信息
    3、服务器通过验证发送给用户一个token
    4、客户端存储token,并在每次请求时附送上这个token值
    5、服务端验证token值,并返回数据

    对比可以得出JWT的好处

    1.性能问题。
    JWT方式将用户状态分散到了客户端中,相比于session,可以明显减轻服务端的内存压力。
    Session方式存储用户id的最大弊病在于Session是存储在服务器端的,所以需要占用大量服务器内存,
    对于较大型应用而言可能还要保存许多的状态,一般还需借助nosql和缓存机制来实现session的存储,如果是分布式应用还需session共享。
    2.单点登录。
    JWT能轻松的实现单点登录,因为用户的状态已经被传送到了客户端。
    token 可保存自定义信息,如用户基本信息,web服务器用key去解析token,就获取到请求用户的信息了。
    我们也可以配置它以便包含用户拥有的任何权限。这意味着每个服务不需要与授权服务交互才能授权用户。
    3.前后端分离。
    以前的传统模式下,后台对应的客户端就是浏览器,就可以使用session+cookies的方式实现登录,
    但是在前后分离的情况下,后端只负责通过暴露的RestApi提供数据,而页面的渲染、路由都由前端完成。因为rest是无状态的,因此也就不会有session记录到服务器端。
    4.兼容性。
    支持移动设备,支持跨程序调用,Cookie 是不允许垮域访问的,而 Token 则不存在这个问题。
    5.可拓展性。
    jwt是无状态的,特别适用于分布式站点的单点登录(SSO)场景。
    比如有3台机器(A、B、C)组成服务器集群,若session存在机器A上,session只能保存在其中一台服务器,此时你便不能访问机器B、C,因为B、C上没有存放该Session,
    而使用token就能够验证用户请求合法性,并且我再加几台机器也没事,所以可拓展性好。
    6.安全性。因为有签名,所以JWT可以防止被篡改。

    JWT的缺点

    当然jwt也是有缺点的如:
    1、JWT在生成token的时候支持失效时间,但是支持的失效时间是固定的,比如说一天。
    但是用户在等出的时候是随机触发的,那么我们jwt token来做这个失效是不可行的,因为jwt在初始化的时候已经定死在什么时候过期了。
    采用其他方案,在redis中存储token,设置token的过期时间,每次鉴权的时候都会去延长时间
    2、jwt不适合存放大量信息,信息越多token越长

    开始搭建我们的项目

    1.1、添加相关jar包
    pom文件
    1.2、编写实体类(我并没有连接数据库,如果您有兴趣可以连接数据库测试)
    实体类
    1.3编写相应的cotroller、server及实现类
    server
    实现类
    controller
    2.1、编写token的工具类(生成、验证)

    import java.util.Date;
    public class TokenUtil {
        private static final long EXPIRE_TIME= 15*60*1000;
        private static final String TOKEN_SECRET="token123";  //密钥盐
        
        /**
         * 签名生成
         * @param user
         * @return
         */
        public static String sign(User user){
            String token = null;
            try {
                Date expiresAt = new Date(System.currentTimeMillis() + EXPIRE_TIME);
                token = JWT.create()
                        .withIssuer("auth0")
                        .withClaim("username", user.getUsername())
                        .withExpiresAt(expiresAt)
                        // 使用了HMAC256加密算法。
                        .sign(Algorithm.HMAC256(TOKEN_SECRET));
            } catch (Exception e){
                e.printStackTrace();
            }
            return token;
        }
        /**
         * 签名验证
         * @param token
         * @return
         */
        public static boolean verify(String token){
            SimpleDateFormat f=new SimpleDateFormat("yyyy 年 MM 月 dd 日 HH 点 mm 分 ss 秒");
            try {
                JWTVerifier verifier = JWT.require(Algorithm.HMAC256(TOKEN_SECRET)).withIssuer("auth0").build();
                DecodedJWT jwt = verifier.verify(token);
                System.out.println("认证通过:");
                System.out.println("issuer: " + jwt.getIssuer());
                System.out.println("username: " + jwt.getClaim("username").asString());
                System.out.println("过期时间:" + f.format(jwt.getExpiresAt()));
                return true;
            } catch (Exception e){
                return false;
            }
    
        }
    }
    

    2.2、添加拦截器

    @Component
    public class TokenInterceptor implements HandlerInterceptor {
    
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception{
    
            if(request.getMethod().equals("OPTIONS")){
                response.setStatus(HttpServletResponse.SC_OK);
                return true;
            }
    
            response.setCharacterEncoding("utf-8");
    
            String token = request.getHeader("admin-token");
            if(token != null){
                boolean result = TokenUtil.verify(token);
                if(result){
                    System.out.println("通过拦截器");
                    return true;
                }
            }
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/json; charset=utf-8");
            PrintWriter out = null;
            try{
                JSONObject json = new JSONObject();
                json.put("success","false");
                json.put("msg","认证失败,未通过拦截器");
                json.put("code","500");
                response.getWriter().append(json.toJSONString());
                System.out.println("认证失败,未通过拦截器");
                //        response.getWriter().write("50000");
            }catch (Exception e){
                e.printStackTrace();
                response.sendError(500);
                return false;
            }
            return false;
    
        }
    
    }
    

    2.3、配置拦截器

    @Component
    public class IntercepterConfig implements WebMvcConfigurer {
    
        private TokenInterceptor tokenInterceptor;
    
        //构造方法
        public IntercepterConfig(TokenInterceptor tokenInterceptor){
            this.tokenInterceptor = tokenInterceptor;
        }
        @Override
        public void addInterceptors(InterceptorRegistry registry){
            List<String> excludePath = new ArrayList<>();
            excludePath.add("/my/login"); //登录
            registry.addInterceptor(tokenInterceptor)
                    .addPathPatterns("/**")
                    .excludePathPatterns(excludePath);
            WebMvcConfigurer.super.addInterceptors(registry);//除了登陆接口其他所有接口都需要token验证
    
        }
    
    }
    

    3、测试
    使用postman进行测试

    当我们的账户和密码错误时
    认证失败
    用户名和密码正确的时候
    验证正确
    返回认证成功,并且带有token,注意保存好我们的token,进行我们下一步的测试。
    将token存放到post请求的headers中key要使用admin-token(因为我们后台获取token是从header的admin-token中获取的)
    验证
    并且后台也打印了载荷中的信息(这个是我们设置的,当然你也可以不设置)
    认证通过
    至此我们的token登陆、验证都测试完毕。接下来我们将运用到spring cloud 的网关上(敬请等待)。

    展开全文
  • 1.jwt 生产token 也可以用MD5 生成token @Component @Slf4j public class JwtUtil { /** * 过期时间 */ private static String accessTokenExpireTime; /** * JWT认证加密私钥(Base64加密) */ private ...

    1.jwt 生产token 也可以用MD5 生成token

    @Component
    @Slf4j
    public class JwtUtil {
        /**
         * 过期时间
         */
        private static String accessTokenExpireTime;
        /**
         * JWT认证加密私钥(Base64加密)
         */
        private static String encryptJWTKey;
    
        /**
         * 解决@Value不能修饰static的问题
         */
        @Value("${accessTokenExpireTime}")
        public void setAccessTokenExpireTime(String accessTokenExpireTime) {
            JwtUtil.accessTokenExpireTime = accessTokenExpireTime;
        }
    
    
        @Value("${encryptJWTKey}")
        public void setEncryptJWTKey(String encryptJWTKey) {
            JwtUtil.encryptJWTKey = encryptJWTKey;
        }
    
        /**
         * @Title: verify @Description: TODO(检验token是否有效) @param: @param
         * token @param: @return @return: boolean @throws
         */
        public static boolean verify(String token) {
            try {
                // 通过token获取密码
                String secret = getUserId(token) + Base64ConvertUtil.encode(encryptJWTKey) + getMobile(token);
                // 进行二次加密
                Algorithm algorithm = Algorithm.HMAC256(secret);
                // 使用JWTVerifier进行验证解密
                JWTVerifier verifier = JWT.require(algorithm).build();
                verifier.verify(token);
                return true;
            } catch (UnsupportedEncodingException e) {
                log.error("JWTToken认证解密出现UnsupportedEncodingException异常:" + e.getMessage());
                return false;
            }
        }
    
        /**
         * @Title: sign @Description: TODO(生成签名) @param: @param mobile @param: @param
         * password @param: @param currentTimeMillis @param: @return @return:
         * String @throws
         */
        public static String getToken(String userId, String mobile, String currentTimeMillis) {
            try {
                // 使用私钥进行加密
                String secret = userId + Base64ConvertUtil.encode(encryptJWTKey) + mobile;
                // 设置过期时间:根据当前时间计算出过期时间。 此处过期时间是以毫秒为单位,所以乘以1000。
                Date date = new Date(System.currentTimeMillis() + Long.parseLong(accessTokenExpireTime) * 1000);
                // 对私钥进行再次加密
                Algorithm algorithm = Algorithm.HMAC256(secret);
                // 生成token 附带account信息
                String token = JWT.create().withClaim(CommonConstant.MOBILE, mobile).withClaim(CommonConstant.USER_ID, userId).withClaim(CURRENT_TIME_MILLIS, currentTimeMillis)
                        .withExpiresAt(date).sign(algorithm);
                return token;
            } catch (UnsupportedEncodingException e) {
                log.error("JWTToken加密出现UnsupportedEncodingException异常:" + e.getMessage());
                throw new RuntimeException("JWTToken加密出现UnsupportedEncodingException异常:" + e.getMessage());
            }
    
        }
    
        /**
         * @Title: getClaim @Description:
         * TODO(获取token中的信息就是withClaim中设置的值) @param: @param token @param: @param
         * claim:sign()方法中withClaim设置的值 @param: @return @return: String @throws
         */
        public static String getClaim(String token, String claim) {
            try {
                // 对token进行解码获得解码后的jwt
                DecodedJWT jwt = JWT.decode(token);
                // 获取到指定的claim,如果是其他类型返回null
                return jwt.getClaim(claim).asString();
            } catch (JWTDecodeException e) {
                log.error("解密Token中的公共信息出现JWTDecodeException异常:" + e.getMessage());
                throw new RuntimeException("解密Token中的公共信息出现JWTDecodeException异常:" + e.getMessage());
            }
        }
    
        /**
         * token 获取用户userID
         *
         * @param token
         * @return
         */
        public static String getUserId(String token) {
            String userId = getClaim(token, CommonConstant.USER_ID);
            return userId;
        }
    
        /**
         * token 获取手机号码
         *
         * @param token
         * @return
         */
        public static String getMobile(String token) {
            String mobile = getClaim(token, CommonConstant.MOBILE);
            return mobile;
        }
    
        /**
         * token 获取手机号码
         *
         * @param token
         * @return
         */
        public static String getCurrentTimeMillis(String token) {
            String currentTimeMillis = getClaim(token, CommonConstant.CURRENT_TIME_MILLIS);
            return currentTimeMillis;
        }
    
    
    }

    登录获取token 并且设置Redis 失效时间 

    private String getToken(Long userId, String mobile) {
        String currentTimeMillis = String.valueOf(System.currentTimeMillis());
        RedisUtil.setEx(RedisKeyPrefix.SFC_REFRESH_TOKEN + mobile, currentTimeMillis,
                Long.parseLong(refreshTokenExpireTime), TimeUnit.SECONDS);
        return JwtUtil.getToken(String.valueOf(userId), mobile, currentTimeMillis);
    }

    新增拦截器,从redis中获取失效时间和所携带token 比对,是否已失效 

     Object currentTimeMillisRedis = RedisUtil.get(RedisKeyPrefix.SFC_REFRESH_TOKEN + mobile);
                    // 获取AccessToken时间戳,与RefreshToken的时间戳对比
                    if (JwtUtil.getCurrentTimeMillis(token).equals(currentTimeMillisRedis.toString())) {

    /

    }

    @Slf4j
    public class AuthorizationInterceptor implements HandlerInterceptor {
    
        @Value("${refreshTokenExpireTime}")
        private String refreshTokenExpireTime;
        @Autowired
        private IUserService userService;
    
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object object) throws Exception {
            String requestURI = request.getRequestURI();
            //对于不用进行验证的接口直接放行
            if (ReleaseAddressUtil.confirm(requestURI)) {
                return true;
            }
            String token = request.getHeader(CommonConstant.AUTHORIZATION);
            if (token == null) {
                // 获取当前请求类型
                String httpMethod = request.getMethod();
                // 获取当前请求URI
                log.info("当前请求 {} Authorization属性(Token)为空 请求类型 {}", requestURI, httpMethod);
                // mustLoginFlag = true 开启任何请求必须登录才可访问
                this.response401(request, response, "请先登录");
                return false;
            }
            String mobile = null;
            String userId = null;
            try {
                mobile = JwtUtil.getMobile(token);
                userId = JwtUtil.getUserId(token);
            } catch (Exception e) {
                e.printStackTrace();
                log.info(e.getMessage());
                this.response401(request,response,"token错误!");
                return false;
            }
            if (StringUtils.isEmpty(mobile)) {
                this.response401(request, response, "token错误!");
                return false;
            }
            if (StringUtils.isEmpty(userId)) {
                this.response401(request, response, "token错误!");
                return false;
            }
            User user = userService.getByUserId(Long.valueOf(userId));
            if (user == null) {
                this.response401(request, response, "账号不存在!");
                return false;
            }
            if (user.getStatus() != null && CommonConstant.DISABLE.equals(user.getStatus())) {
                this.response401(request, response, "帐号已被锁定,禁止登录!");
                return false;
            }
            try {
                if (JwtUtil.verify(token) && RedisUtil.hasKey(RedisKeyPrefix.SFC_REFRESH_TOKEN + mobile)) {
                    Object currentTimeMillisRedis = RedisUtil.get(RedisKeyPrefix.SFC_REFRESH_TOKEN + mobile);
                    // 获取AccessToken时间戳,与RefreshToken的时间戳对比
                    if (JwtUtil.getCurrentTimeMillis(token).equals(currentTimeMillisRedis.toString())) {
                        UserInfo userInfo = new UserInfo();
                        userInfo.setId(user.getId());
                        userInfo.setUserId(user.getUserId());
                        userInfo.setMobile(user.getMobile());
                        userInfo.setNickname(user.getNickname());
                        UserContext.set(userInfo);
                        return true;
                    }
                }
            } catch (Exception e) {
                // 认证出现异常,传递错误信息msg
                String msg = e.getMessage();
    			
          this.response401(request, response, msg);
                    return false;
            }
            return false;
        }
    
    
        @Override
        public void postHandle(HttpServletRequest httpServletRequest,
                               HttpServletResponse httpServletResponse,
                               Object o, ModelAndView modelAndView) {
    
        }
    
        @Override
        public void afterCompletion(HttpServletRequest httpServletRequest,
                                    HttpServletResponse httpServletResponse,
                                    Object o, Exception e) {
    
            //关闭threadLocal
            UserContext.remove();
        }
    
        /**
         * 缺少权限内部转发至401处理
         *
         * @param request
         * @param response
         * @param msg
         */
        private void response401(ServletRequest request, ServletResponse response, String msg) {
            HttpServletRequest req = (HttpServletRequest) request;
            try {
                req.getRequestDispatcher("/app/user/login/unauthorized?message=" + msg).forward(request, response);
            } catch (Exception e) {
                log.error("未授权登录{}", e);
            }
        }
    
    
    }

     

    展开全文
  • 先说下全部情况,我这边Http 方式采用的是 OKhttp+Retrofit后台一共分为三种token,分别是实名token(accessToken),匿名token(oauthToken),刷新token(refreshToken),不同的token用途不一样,有的作为请求参数放在...
  • Shiro重构:整合token和cookie实现登陆及验证 认证服务开始只支持PC端的cookie认证方式,因业务需要,要对小程序、H5、App等移动端设备进行认证,这里复用认证服务。由于小程序不支持cookie认证方式,采用token认证...
  • 在laravel8框架中除了登录的路由不用使用token验证,然后当我们进入其他控制的时候都需要进行token验证,为了确保用户是否登录
  • } 通过以上的改造,就可以使用在微信小程序里面使用token来验证身份,并执行手机端的业务逻辑。避免了重写业务逻辑的烦恼。 当然,也可以通过写一个cookie代理的脚本,实现token模拟cookie验证,提供思路给各位。 1...
  • 在前后端完全分离的情况下,Vue项目中实现token验证大致思路如下: 1、第一次登录的时候,前端调后端的登陆接口,发送用户名和密码 2、后端收到请求,验证用户名和密码,验证成功,就给前端返回一个token 3、前端...
  • 用户名密码登录到系统是必然的模式,但是很多系统或日常中,可以有很多其他身份登陆到对应系统中,比如手机号码、邮箱、微信等,在oauth2中要实现对应登录方式,必须要实现对应的Filter、Provider、对应token以及...
  • SpringSecurity默认提供了两种登陆,一种basic登陆一种表单登陆(分别在一三章有讲到),但是如果我们要实现其他方式的登陆(例如邮箱登陆手机号登陆)又该怎么做呢? 第二章中讲到了Security的登录原来,以及最后...
  • Token登录认证详解

    万次阅读 多人点赞 2020-05-25 18:44:35
    Token 认证的来龙去脉 前后端分离使用 Token 登录解决方案 理解Cookie和Session机制 基于 Cookie/Session 的认证方案 Cookie Cookie的工作原理 由于HTTP是一种无状态的协议,服务器单从网络连接上无从知道客户...
  • 现在有一个需求就是改造 oauth2.0 实现手机号码可以登录 需要重几个类 第一个类 PhoneLoginAuthenticationFilter public class PhoneLoginAuthenticationFilter extends ...
  • 手机号验证码登陆概述搭建基础架构认证流程定义token定义过滤filter接下来是自定义手机号验证码登陆鉴证provider修改UserDetailService的实现类为生成验证码接口登陆接口测试未登录状态用户名 密码登陆手机号 ...
  • java实现基于JWT的token登陆认证 前言 之前基于session的登录方式,是在用户登录成功后将用户信息存入到session中,这样不利于程序的横向扩展, 如果将项目部署多份,会出现session漂移的问题,并且随着登录用户的...
  • 微信小程序登陆 + 基于JWT的Token 验证 + 内部用户登陆系统 公司需要做一个用于内部员工的培训系统的小程序,之前只是了解过,但是并没有自己动手做过小程序,以下是记录自己这次的开发过程。 文档层解析 微信官方...
  • 基于 Cookie/Session 的认证方案 Cookie Cookie的工作原理 由于HTTP是一种无状态的协议,服务器单从网络连接上无从知道客户身份。怎么办呢?... HttpInterceptor => 401: '用户登陆状态失效,请重新登陆。'
  • app开发调试工具_app开发token使用 安卓平板电脑怎样下载软件 首先,下载完后,可以把APK通过数据线等复制到SD卡,然后通过文件管理在SD卡中打开APK文件进行安装,但这种方法比较麻烦,笔者建议通过魔乐手机助手...
  • 其实把流程捋清楚了也很简单,题主说到了返回用户的Token信息。在大多数情况下Token和Cookie的作用是一样的,用来保存用户的某一些状态。Cookie一般由浏览器或者客户端自动维护失效状态,服务端也可以根据请求头中的...
  • 因为需要获取图片的response数据,因为这个不是走的接口,所以在axios的response拦截里面是回去不到图片的response的token。所以 需要给图片自定义一个ajax,在图片拦截里面去获取数据。 <template> <...
  • JWT生成token及过期处理方案

    千次阅读 2021-01-27 03:35:27
    ## 业务场景在前后分离场景下,越来越多的项目使用token作为接口的安全机制,APP端或者WEB端(使用VUE、REACTJS等构建)使用token与后端接口交互,以达到安全的目的。本文结合stackoverflow以及本身项目实践,试图总结...
  • 一般的流程都是登录的时候返回一个代表此登录的token,以后所有接口都带上此token,在所有接口调用之前拦截验证,一般都是通过AOP或者一个Filter、拦截来实现。而退出的时候调用接口将此token删除即可。一般地,...
  • uniapp无痛刷新token

    2021-06-19 01:42:46
    用户登录拿到token,但由于token是有时限的,刷新token的时候需要无声无息,用户还能继续之前的请求。这里我的想法是,当token到期,返回状态码401,就发起刷新token接口,拿到新的token就把之前的请求再发送一遍,...
  • 其实所说的被挤下线功能,就是一个账号在A客户端保持登陆状态,然后又在B客户端进行了登陆操作,那么A客户端就会被顶下线 很多伙伴在开发自己公司产品的时候,一般都会考虑用户账号安全,或者用户账号功能限制等...
  • 后端登录功能实现——token技术 内容参考自以下博客: https://www.yunliyunwai.cn/blog/detail/da87ec1283706f0c0995a9c235f2eb31(过度借鉴,请勿在意~) 【详细而又具体有逻辑的内容请直接点击链接访问,笔者...
  • 前后端分离中的无痛刷新token机制

    千次阅读 2021-01-14 12:23:41
    今天我们来说一说前后端分离中的无痛刷新token机制,在手机app中应该经常用到,大家都知道在前后端是以token的形式交互,既然是token,那么肯定有它的过期时间,没有一个token是永久的,永久的token就相当于一串永久...
  • 拼多多TOKEN授权

    千次阅读 2021-01-13 07:08:33
    今天分享一下拼多多TOKEN的理解,首先Token的定义是什么?概念Token被翻译成为('令牌','标记')在计算机中的含义也差不错('计算机身份认证安全令牌'),token其实说的更通俗点可以叫暗号,在一些数据传输之前,要先...
  • Token-简单使用

    2021-08-23 21:59:37
    Token-简单使用 (1)登录 -> 后端服务 ->...传统的token是某个用户登陆之后,服务器返回一个token给用户保存,这个token可能是随机几个字母的组合,并且服 务保留同一份token(比如用redis存储tok
  • token在项目生成和使用

    千次阅读 2021-01-30 11:09:41
    目录用户登陆,发送手机号码和验证码后台接收参数,查找用户,用户存在就生成token,返回给前端前端登陆成功,把token存到vuex(做持久化)使用axios拦截,读取vuex中的token,并放入请求头请求其他接口,就会带上token后台...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 4,131
精华内容 1,652
关键字:

token号手机登录器