精华内容
下载资源
问答
  • 最近写的项目中又写了一遍前后分离的微信授权登录功能(本人后端),顺便梳理下,不想看可直接看后面的干货 ...前端在访问除登录请求或业务需要的请求外,前端都需要将token携带在请求头中,后端接收到token

    最近写的项目中又写了一遍前后分离的微信授权登录功能(本人后端),顺便梳理下,不想看可直接看后面的干货

    1. 通过登录拦截强制未登录用户进入授权界面,无法直接访问其他页面
    2. 用户进入授权界面完成授权会返回code,后端根据code进行一系列操作后将用户注册保存至数据库(后端会进行一些处理比如判断主动授权、静默授权,是否更新过信息)
    3. 同时会生成token,后端将token保存在redis中,前端保存在storage中
    4. 前端在访问除登录请求或业务需要的请求外,前端都需要将token携带在请求头中,后端接收到token进行查找用户是否存在,校验token等操作

    一、引入依赖

    <dependency>
           <groupId>com.auth0</groupId>
           <artifactId>java-jwt</artifactId>
           <version>3.4.0</version>
     </dependency>
    

    二、Jwt工具类

    @Slf4j
    public class JwtUtil {
    
        public static void main(String[] args) {
            System.out.println(generate(1, DateUtil.date().offset(DateField.DAY_OF_MONTH, 1)));
            System.out.println(getId("eyJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJKZXJzZXktU2VjdXJpdHktQmFzaWMiLCJzdWIiOiIxIiwiZXhwIjoxNjI2MDA4NzcyLCJpYXQiOjE2MjU5MjIzNzJ9.arWl-hagLZ8xlfacXwUs-iSTjH3UVGIK68lEYMOYNPI"));
        }
    
        private static final String KEY = "1234qwer";
    
        public static String generate(Integer id, Date expiration) {
            if (id == null) {
                throw new NullPointerException("null id is illegal");
            }
            if (expiration == null) {
                throw new NullPointerException("null expiration is illegal");
            }
            return Jwts.builder()
                    .setIssuer("Jersey-Security-Basic")
                    .setSubject(id.toString())
                    .setExpiration(expiration)
                    .setIssuedAt(new Date())
                    .signWith(SignatureAlgorithm.HS256, KEY)
                    .compact();
        }
    
        public static boolean verify(String token) {
            try {
                Jwts.parser().setSigningKey(KEY).parseClaimsJws(token.trim());
                return true;
            } catch (Exception e) {
                log.error("无效的token:{}", token);
                return false;
            }
        }
    
        public static Integer getId(String token) {
            if (verify(token)) {
                Jws<Claims> claimsJws = Jwts.parser().setSigningKey(KEY).parseClaimsJws(token);
                return Convert.toInt(claimsJws.getBody().getSubject(), null);
            }
            return null;
        }
    }
    

    三、新建WebMvc配置

    @Configuration
    public class WebMvcConfig implements WebMvcConfigurer {
    
        @Value("${savePath:/data/springboot-demo/file/}")
        private String savePath;
    
        @Override
        public void addResourceHandlers(ResourceHandlerRegistry registry) {
            registry.addResourceHandler("/media/**")
                    .addResourceLocations("file:" + savePath)
                    .setCacheControl(CacheControl.maxAge(864000, TimeUnit.SECONDS).cachePublic());
        }
    
        /**
         * 拦截器
         * @param registry
         */
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(loginInterceptor())//添加拦截器
                    .excludePathPatterns("/user/loginByCode", "/user/loginByOpenId")//对应的不拦截的请求
                    .addPathPatterns("/**"); //拦截所有请求
        }
    
        /**
         * 自己写的拦截器
         * @return
         */
        @Bean
        public LoginInterceptor loginInterceptor() {
             return new LoginInterceptor();
         }
    }
    

    四、新建登陆拦截器

    public class LoginInterceptor implements HandlerInterceptor {
    
        @Autowired
        UserMapper userMapper;
    
        private static final Logger log = LoggerFactory.getLogger(LoginInterceptor.class);
        /**
         * 进入controller层之前拦截请求
         *
         * @param httpServletRequest
         * @param
         * @param o
         * @return
         * @throws Exception
         */
        @Override
        public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse response, Object o) throws Exception {
            String token = httpServletRequest.getHeader("Authorization");
            if (token == null) {
                throw new RuntimeException("未携带token");
            }
            Integer id = JwtUtil.getId(token);
            User user = userMapper.selectOne(new QueryWrapper<User>().eq("id", id));
            if (user == null) {
                throw new RuntimeException("用户不存在,请重新登录");
            }
            // 验证token
            boolean verify = JwtUtil.verify(token);
            System.out.println(verify);
            if (verify) {
                return true;
            }
            return false;
        }
        //访问controller之后 访问视图之前被调用
        @Override
        public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
            log.info("--------------处理请求完成后视图渲染之前的处理操作---------------");
        }
        //访问视图之后被调用
        @Override
        public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
            log.info("---------------视图渲染之后的操作-------------------------0");
        }
    
    展开全文
  • 【Sa-Token】一、Sa-Token实现登录功能

    千次阅读 2021-08-01 17:52:53
    Sa-Token 介绍 Sa-Token是一个轻量级Java权限认证框架,主要解决:登录认证、权限认证、Session会话、单点登录、OAuth2.0、微服务网关鉴权 等一系列权限相关问题 开发文档地址:Sa-Token ...

    Sa-Token 介绍

    Sa-Token是一个轻量级Java权限认证框架,主要解决:登录认证、权限认证、Session会话、单点登录、OAuth2.0、微服务网关鉴权 等一系列权限相关问题

    开发文档地址:Sa-Token 开发文档

    http://sa-token.dev33.cn/doc/index.html#/
    

    一、引入 Sa-Token

    <!-- Sa-Token 权限认证, 在线文档:http://sa-token.dev33.cn/ -->
    <dependency>
        <groupId>cn.dev33</groupId>
        <artifactId>sa-token-spring-boot-starter</artifactId>
        <version>1.24.0</version>
    </dependency>
    <!-- web依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- lombok插件 -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    

    其余依赖请自行引入

    二、实现登录

    • 1、登录DTO类
    import lombok.Data;
    
    @Data
    public class LoginDTO {
    
        /**
         * 账户
         */
        private String username;
    
        /**
         * 密码
         */
        private String password;
    
        /**
         * 验证码uuid
         */
        private String uuid;
    
        /**
         * 验证码
         */
        private String code;
    
        /**
         * 记住登录,默认为:true
         */
        private Boolean rememberMe = true;
    }
    
    
    • 2、登录方法
    /**
     * 登录
     *
     * @param loginDTO
     * @return
     */
    @PostMapping("login")
    public RES login(@RequestBody LoginDTO loginDTO) {
        return loginService.login(loginDTO);
    }
    
    • 3、登录实现方法
    @Override
    public RES login(LoginDTO loginDTO) {
        if (null == loginDTO) {
            return RES.no("登录失败");
        }
        if (StringUtils.isBlank(loginDTO.getUsername())) {
            return RES.no("请输入用户名");
        }
        if (StringUtils.isBlank(loginDTO.getPassword())) {
            return RES.no("请输入密码");
        }
        if (StringUtils.isBlank(loginDTO.getCode())) {
            return RES.no("请输入验证码");
        }
        if (StringUtils.isBlank(loginDTO.getUuid())) {
            return RES.no("验证码已过期");
        }
        // 验证码
        String code = redisUtil.getAndDelete(RedisConst.Key.KAPTCHA_KEY + loginDTO.getUuid());
        // 不区分大小写
        if (StringUtils.isBlank(code) || !code.equalsIgnoreCase(loginDTO.getCode())) {
        	return RES.no("验证码不正确");
        }
        // 验证账户
        LambdaQueryWrapper<SysUserInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysUserInfo::getAccount, loginDTO.getUsername());
        SysUserInfo one = sysUserInfoService.getOne(queryWrapper, false);
        // 不存在
        if (null == one) {
        	return RES.no("账户不存在");
        }
        // 被冻结
        if (1 == one.getStatus()) {
        	return RES.no("账户已被冻结");
        }
        // 密码不正确
        if (!PasswordUtils.getPassword(one.getAccount(), loginDTO.getPassword()).equals(one.getPassword())) {
        	return RES.no("账户或密码错误");
        }
        // 执行登录
        StpUtil.login(one.getId(), loginDTO.getRememberMe());
        // 返回token
        return RES.ok(LoginEnums.LOGIN_SUCCESS.getMsg(), StpUtil.getTokenValue());
    }
    

    这样,我们的登录就完成了,登录成功后,会接收到后端返回的 token 信息,后面通过传递此 token 信息就能鉴别用户的身份了

    如您在阅读中发现不足,欢迎留言!!!

    展开全文
  • 基于Redis+Token实现登录认证

    千次阅读 2021-04-19 15:59:27
    登录认证即分为登录和认证两部分,下面聊下他们的实现逻辑。 1 登录 前端调用后端的登录接口,后端验证用户名和密码等成功后,则做下面两个主要工作: 1 以用户id为key,生成的token为value,缓存到redis中并设置...

    登录认证即分为登录和认证两部分,下面聊下他们的实现逻辑。

    1 登录

    前端调用后端的登录接口,后端验证用户名和密码等成功后,则做下面两个主要工作:

    • 1 以用户id为key,生成的token为value,缓存到redis中并设置过期时间
    • 2 以生成的token为key,用户信息为value,缓存到redis中并设置过期时间

    最后将token及用户信息返回给前端,前端将token放在header中,调用其他接口时都携带者。
    如果退出登录,则将上面的两条信息从redis中删除即可

    2 认证

    前端调用其他接口时,先经过一个全局拦截器,这个全局拦截器可以实现Spring的HanderInterceptorAdapter并重写preHandle和afterCompletion方法。

    • 1 在preHandle方法中,首先获取前端请求header中的token,并校验该token是否有效的存放在redis中,如果有效,则判断是否需要token续期(例如:token缓存在redis中的过期时间是2小时,如果token当前剩余时间小于(2-1)小时,则将token的过期时间重新设置成2小时);然后将token及用户信息保存到本地ThreadLocal中;最后返回true。
    • 2 在afterCompletion方法中,将ThreadLocal中的信息清除。我们知道:当一个接口请求处理完成后会调用afterCompletion方法,所以这个ThreadLocal也就是当前接口请求有效,当一个接口请求执行完成后,则将ThreadLocal中的用户信息清除。

    为什么不使用JWT的方案?

    1、使用了JWT,服务端无法对用户请求进行管理,比如:统计登录用户数、统计一个用户登录了多少次。
    2、使用了JWT,服务端无法剔除一个已登录的用户,因为JWT一旦生成,在失效之前,总是有效的。

    延申

    JWT全称JSON Web Token,由三部分组成:header(头部,用于描述关于该JWT的最基本的信息,例如其类型以及签名所用的算法等)、payload(载荷,就是存放有效信息的地方,在这一部分中存放token过期时间、签发时间等,且payload是明文的)和signature(签名。服务器端可以自行选择一个算法和一个secret,与payload拼接上,得到一个签名,secret并不会在网络中传输,所以客户端无法伪造一个JWT)。

    扫码登录:https://mp.weixin.qq.com/s/T3YOppJqW85oK7mUujEReA

    展开全文
  • redis+token实现登录状态 /* * 登录后存储用户对象的redis函数 */ @RequestMapping(value = "/loginRedis",method=RequestMethod.POST) public AppResult loginRedis(UserInfo userInfo){ String uuid = ...
                                   redis+token实现登录状态
    
       /*
        * 登录后存储用户对象的redis函数
        */
        @RequestMapping(value = "/loginRedis",method=RequestMethod.POST)
        public AppResult loginRedis(UserInfo userInfo){
            String uuid = Utils.getUUID();
            String value = JSON.toJSONString(userInfo);
            stringRedisTemplate.opsForValue().set(uuid,value);
            //30分钟后自动退出
            stringRedisTemplate.expire(uuid,30, TimeUnit.MINUTES);
            return  AppResult.successData("token",uuid);
    
        }
    
        /*
         * 调用接口的时候的登录状态的授权
         */
        @RequestMapping(value = "/isLogin",method=RequestMethod.GET)
        @ResponseBody
        public UserInfo isLogin(@RequestParam("token") String token){
            String userInfoStr = stringRedisTemplate.opsForValue().get(token).toString();
            if (userInfoStr==""||userInfoStr==null){
                return null;
            }else {
                //刷新redis的值30分钟
                stringRedisTemplate.expire(token,30, TimeUnit.MINUTES);
               //返回登录的用户对象
                UserInfo userInfo =  JSON.parseObject(userInfoStr,UserInfo.class);
               return  userInfo;
            }
        }
    
    展开全文
  • 一般的登录权限框架有spring security和shiro两种,但是如果只是单单实现一个登录功能,没有更多的权限交互,引入沉重的框架来处理反而会出现很多问题或者加重程序的处理效率,所以,用自定义的token实现登录功能在一些...
  • token实现登录拦截

    热门讨论 2021-10-18 18:12:23
    简单的利用sessionStorage机制以及路由中的beforeEach来实现登录拦截,当然有token是最好的。 主界面,同过setItem来存储登录的判断条件。 sessionStorage.setItem('isLogin',1);//登录判断 index.js { ...
  • 前言放假之前做了几个小项目+课设,都用到了token实现登录验证和权限判断,然鹅当时和同组的小伙伴也都是第一次接触到了token,于是乎都是一脸懵逼(xjbx)的写完了登录验证的前后端逻辑(我写前端,同组的小伙伴写后端...
  • 有关token实现单点登录步骤

    千次阅读 2021-01-02 21:32:59
    有关token实现单点登录步骤 服务端 1. 客户端使用username和pwd进行请求登录 2. 服务端收到请求,验证用户名和密码 3. 验证通过之后,服务端会签发一个token令牌,(存储到redis 还可以设置有效时间)再把token发送...
  • pom文件 <dependency> <groupId>com.auth0</groupId> <artifactId>java-jwt</artifactId> <version>3.5.0</version>...生成token import com.alibaba.fastjs
  • 使用redis实现登录token的需求 需求分析: 我们用户登录成功后, 需要记录用户的基本信息,当前登录时间或者你可能会记录其他什么 比如用户浏览了什么东西。 token流程,生成一段随机字节作为令牌,服务器可以根据...
  • uni-app实现登录保存Token

    千次阅读 2020-12-19 16:01:54
    详情查看:Sliver Rest Wp api:全功能的WordPress api工具引言在上一小节中我向大家展示了如何在uni中判断用户是否登录,在本小节中我将利用前面的登录代码实现token的存储。开始后端打开我们的主题目录下面的login...
  • } public static boolean validToken(String token, String password) { String confirm = getToken(password); if (confirm.equals(token)) { return true; } else { return false; } } public static ...
  • 记录一下前后端分离开发时使用token进行登录退出以及未登录的拦截功能,以供参考 文章目录依赖登录后端Util工具类Model层Mapper层Service层Controller层前端HTML数据区方法区效果图登出拦截后端定义...
  • Springboot+Vue前后端分离实现用户登录Token权限验证以及登录Token状态保存
  • Token之前的博客已经介绍了各种登录的方式,现在直接介绍一种现在比较流行的登录方式,无状态登录,只需要客户端携带令牌就能登陆,服务器不再存储登录状态。突然粉丝量爆棚,开心死了,所以抓紧写一篇硬核代码,...
  • php用token登录认证

    2021-01-29 17:10:14
    实现登录状态保持与身份认证的方式通常有两种:session结合数据库、token。 两者相比较,token有较多优点。 ① token可以存储在任何位置(比如cookie或local storage) ② token更容易跨域 ③ to.
  • print("返回体是:",r.text) print("状态码是:",r.status_code) if __name__=="__main__": test_login() 参考资料 用python脚本实现一次获取token,多次使用token Python自动化—实现获取token
  • 我的场景是前台为react也就是基于axios进行请求的后台就是通俗的java后台服务,具体实现步骤如下1)首先前台进行发送登录请求,后台进行登录校验2)后台生成token,返回给前台,前台可以将之保存在浏览器中的...
  • Sa-Token简单登录认证

    2021-10-14 17:48:27
    下面是一个简单的登录认证示例,以一个spring boot+thymeleaf来实现具体逻辑 首先导入sa token的Maven依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>...
  • 在前后端完全分离的情况下,前端项目中实现token验证大致思路如下: 1、第一次登录的时候,前端调后端的登陆接口,发送用户名和密码 2、后端收到请求,验证用户名和密码,验证成功,就给前端返回一个token 3、前端...
  • IT小奋斗2021-01-13 21:48:33...JWT (JsonWebToken),是实现token技术的一种解决方案,由三部分组成: header(头)、payload(载体)、signature(签名)。1、头:HS384 HS512 RS256 RS384 RS512 ES256 ES384 ES512 PS256...
  • 基于项目需求, 我们要实现一个基于redis实现token登录验证,该如何实现呢:后端实现:1.引入redis相关的依赖org.springframework.bootspring-boot-starter-data-redisorg.springframework.sessionspring-session-...
  • //登录实体类 @Data public class LoginUser implements Serializable{ private static final long serialVersionUID = 1L; private Integer id; private String username; private String password; ...
  • 前端应该学习的Token登录认证

    千次阅读 2021-03-26 00:39:07
    时序图表示 使用 Token 和 Refresh Token 的时序图如下: 1)登录 2)业务请求 3)Token过期,刷新 Token 上面的时序图中并未提到 Refresh Token 过期怎么办。不过很显然,Refresh Token 既然已经过期,就...
  • 解决Github 使用token登录 〇、问题 自2021年8月13号开始,Github将不再接受用户使用账户和密码进行Git操作。 -<zhangruiyuan@zhangruiyuandeMacBook-Pro.local:~/TaroProjects/GFLMiniProgram [main]>- -&...
  • 设计思路用户发出登录请求,带着用户名和密码到服务器经行验证,服务器验证成功就在后台生成一个token返回给客户端客户端将token存储到cookie中,服务端将token存储到redis中,可以设置存储token的有效期。...
  • 1、登录后存储用户对象的redis函数 @Autowired private StringRedisTemplate redisTemplate; @PostMapping(value = "/login") public R login(UserInfo userInfo){ String uuid = Utils.getUUID(); String ...
  • 实现原理 [不知道对不对] 前端传来用户名密码(例如name、password) 后端接收生成对象(user) 生成uuid作为token令牌(就是一个唯一的字符串str) 将token作为key,user作为valued存到redis 将token返回给前端 前端...
  • vue实现token登录

    2021-03-26 14:51:18
    token实现登录的是利用vuex来进行管理,具体思路如下 1.在用户登录后获取到用户的登录信息,并获取信息中的token值将token放入sessionStroge中 //省略请求过程 if (res.data.code == '00000') {//请求成功 this...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 109,049
精华内容 43,619
关键字:

token实现登录