怎么实现同一账号只能在一台设备登录

同一账号只能在一台设备登录实现思路。

注意:登录是在白名单(直接放行的接口)。生成的token携带账号信息。

1.用户每次登录生成token时,将账号当成key,token当成value,以token的过期时间存入redis中。

2.用户访问的时候,在拦截器解析token,获取账号,拿账号去redis中获取value,如果是value的token与当前用户携带过来的token一致就放行。如果不一致,则告诉前端重复登录,让前端清除token,跳转到登录页面。

3.用户在另一台设备登录时,也是存入redis,这样就刷新了token的值和redis的过期时间。

这是我的一个实现思路,有没有大佬可以指点,互相学习一下。
在这里插入图片描述
写了个小demo,主要代码如下:

1.拦截器代码:

package com.yblue.config;import com.yblue.dto.Payload;
import com.yblue.dto.UserInfo;
import net.minidev.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.HttpMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;/*** @author: JiaXinMa* @description: 解决跨域和权限* @date: 2021/3/26*/
public class AuthInterceptor implements HandlerInterceptor {@AutowiredFilterProperties filterProperties;@AutowiredJwtProperties jwtProps;@AutowiredStringRedisTemplate redisTemplate;@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {//表示接受任意域名的请求,也可以指定域名response.setHeader("Access-Control-Allow-Origin", request.getHeader("origin"));//该字段可选,是个布尔值,表示是否可以携带cookieresponse.setHeader("Access-Control-Allow-Credentials", "true");response.setHeader("Access-Control-Allow-Methods", "GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS");response.setHeader("Access-Control-Allow-Headers", "*");//预请求,这里可以不加,但是其他语言开发的话记得处理options请求// 如:异步请求的时候前端发两次请求,其中一次是测试通不通if (HttpMethod.OPTIONS.toString().equals(request.getMethod())) {return true;}//获取当前访问的URL接口后的路径String uri = request.getRequestURI(); //如:/api/user/xxx//判断uri地址,如果为 /error 则可能是请求方式、参数、访问路径不对if (uri.equals("/error")) {this.responseError(response, 405, "请求方式、参数类型、访问地址错误、数据库方面异常!");return false;}//1.判断当前访问路径是否在白名单列表中List<String> allowPaths = filterProperties.getAllowPaths();for (String allowPath : allowPaths) {if (uri.contains(allowPath)) {//如果在,直接放行了return true;}}//2.校验token合法性Payload<UserInfo> payload = null;try {String token = request.getHeader(jwtProps.getCookie().getCookieName());
//            String token = CookieUtils.getCookieValue(request, jwtProps.getCookie().getCookieName());payload = JwtUtils.getInfoFromToken(token, jwtProps.getPublicKey(), UserInfo.class);String redisToken = redisTemplate.opsForValue().get(payload.getInfo().getUsername());if (token.equals(redisToken)) {return true;} else {this.responseError(response, 401, "您的账号在另一台设备上登录,请及时修改密码!");}} catch (Exception e) {this.responseError(response, 401, "登录失效或未登录!");return false;}//3.如果你的想校验权限、角色,可以在你的userInfo里封装,然后在下面验证,不过我现在的userInfo没放
//        UserInfo userInfo = payload.getInfo();
//        List<Module> modules = userInfo.getModules();
//        for (Module module : modules) {
//            if (uri.equals(module.getUrl())) {//判断用户是否有访问路径的权限
//                return true;
//            } else {
//                this.responseError(response, 403, "权限不足!");
//            }
//        }return false;}/*** @author: JiaXinMa* @description: 响应错误代码 处理响应错误信息的方法,可以拿去用* @date: 2021/8/23*/public void responseError(HttpServletResponse response, Integer code, String returnMessage) {response.setCharacterEncoding("UTF-8");response.setContentType("application/json; charset=utf-8");JSONObject jsonObject = new JSONObject();try {jsonObject.put("code", code);jsonObject.put("msg", returnMessage);response.getWriter().append(jsonObject.toString());} catch (Exception e) {e.printStackTrace();}}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {}}

2.业务层代码:

package com.yblue.service;import com.yblue.config.JwtProperties;
import com.yblue.config.JwtUtils;
import com.yblue.domain.User;
import com.yblue.dto.Payload;
import com.yblue.dto.UserInfo;
import com.yblue.exception.pojo.ExceptionEnum;
import com.yblue.exception.pojo.MdException;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;/*** @author: JiaXinMa* @description: 验证授权 Service层* @date: 2021/3/25*/
@Service
@Transactional
public class AuthService {@AutowiredUserService userService;@Autowiredprivate JwtProperties jwtProps;@Autowiredprivate StringRedisTemplate redisTemplate;/*** @author: JiaXinMa* @description: 登录* @date: 2021/5/28*/public Map login(String username, String password) {try {Map<String, Object> map = new HashMap();//存放token和用户信息//1. 判断用户名和密码是否正确User loginUser = userService.findUserByNameAndPwd(username, password);UserInfo userInfo = new UserInfo(loginUser.getUserId(), loginUser.getName(), loginUser.getUsername());//2.生成tokenString token = this.generateToken(userInfo);map.put(jwtProps.getCookie().getCookieName(), token);map.put("userInfo", userInfo);//3.将token放进redis中redisTemplate.opsForValue().set(loginUser.getUsername(), token, 60, TimeUnit.MINUTES);return map;} catch (Exception e) {throw new MdException(ExceptionEnum.INVALID_USERNAME_PASSWORD);}}/*** @author: JiaXinMa* @description: 生成token* @date: 2021/4/6*/public String generateToken(UserInfo info) {//利用JwtUtils+私钥生成加密token//以前是的工具类是通过cookies带过去了,然后现在他们说要放在请求头上,所以那些类名字没改,不妨碍业务的使用return JwtUtils.generateTokenExpireInMinutes(info, jwtProps.getPrivateKey(), jwtProps.getCookie().getExpire());}
}

3.控制层代码

package com.yblue.controller;import com.yblue.domain.User;
import com.yblue.service.AuthService;
import com.yblue.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;import java.util.Map;/*** @author: JiaXinMa* @description: 验证 控制器* @date: 2021/5/28*/
@Slf4j
@RestController
@RequestMapping("/api")
public class AuthController {@AutowiredAuthService authService;@AutowiredUserService userService;@PostMapping("/auth/login")public Map login(@RequestBody User user) {log.info("/api/auth/login:{}", user);return authService.login(user.getUsername(), user.getPassword());}@GetMapping("/user/findByUserId")public User findByUserId(@RequestParam("userId") Integer userId) {log.info("/api/user/findByUserId:{}", userId);return userService.findByUserId(userId);}
}

效果如下图:

第一次:
在这里插入图片描述
第二次:
在这里插入图片描述
如果有些小伙伴有更好的解决方案或者觉得该方案有什么不足的,可以提出来一起讨论交流。

想看更多精彩内容,可以关注我的博客园
我的博客园

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/71758.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

排名第一的亚马逊关键词工具

如果你还不知道如何寻找并且确定属于自己产品的关键词&#xff0c;看完这篇文章你就会有所启发了。 做电商平台的&#xff0c;甚至可以说做网站SEO的人都知道&#xff0c;流量其实可以理解为搜索词的争夺。谁占据了搜索词下的靠前位置&#xff0c;意味着高点击和高转化。经典的…

为什么加购可以让亚马逊关键词上首页?

其实关键词上首页的原理就是加购。通过加购&#xff0c;可以优化关键词的排名&#xff0c;配合测评能提高转化率&#xff0c;提高listing权重&#xff0c;使产品的排名更高&#xff0c;把最重要的位置给主推词&#xff0c;最大限度保证主推词的权重&#xff0c;后期重点推广关键…

亚马逊关键词在哪里找准确一点?

编写一条listing&#xff0c;最核心也是最关键的就是找到与这条listing最匹配的关键词。 第一&#xff1a;亚马逊搜索框的下拉框 第二&#xff1a;亚马逊后台广告报表下载的关键词 选取关键词报表中点击率及 转化率高的关键词&#xff0c;可以作为关键词素材使用。 第三&#x…

如何正确的进行亚马逊关键词研究

本篇文章将提供实用的亚马逊关键词方法以及如何改进关键词搜索结果。您必须采取以下三个步骤来为您的亚马逊列表收集关键词信息&#xff1a; 第 1 步&#xff1a;寻找您的种子关键词 首先卖家应该找到四到五个种子关键词&#xff0c;这些是能够描述您的产品是什么的主要短语。…

lazada按关键字搜索商品API接口

lazada按关键字搜索商品 API接口&#xff0c;在 lazada上搜索产品&#xff0c;如果只需要搜索单个产品的话&#xff0c;那么直接在搜索框输入“关键字”即可&#xff0c;如果需要多个产品&#xff0c;那么则需要进行关键字扩展。 lazada按关键字搜索商品 API接口分为两部分&am…

如何利用亚马逊关键词进行引流?权威关键词设置技巧来了

利用关键词获取流量是运营店铺至关重要的一步,那么亚马逊卖家怎样设置关键词才能更高效精准地引流呢?本期的亚马逊运营知识,船长BI将为大家分享关于亚马逊关键词的设置技巧。 在掌握关键词设置技巧之前,必须弄懂关键词的定义。 01、关键词的认知 关键词是代表产品的词组…

提高亚马逊关键词搜索排名的方法

亚马逊关键词搜索排名在首页是很重要的&#xff0c;因为客户都是通过关键词搜索产品&#xff0c;如果你的产品通过关键词搜索出来排在了后面几页&#xff0c;那么消费者基本上都不会去查看及购买&#xff0c;因此想要产品能被发现及购买&#xff0c;提高亚马逊关键词的搜索排名…

lazada按关键字搜索商品 API

为了进行电商平台 的API开发&#xff0c;首先我们需要做下面几件事情。 1&#xff09;开发者注册一个账号 2&#xff09;然后为每个Lazada应用注册一个应用程序键&#xff08;App Key) 。 3&#xff09;下载 Lazada API的SDK并掌握基本的API基础知识和调用 4&#xff09;利…

亚马逊刷关键词软件——亚马逊鲲鹏系统

亚马逊刷关键词是为了让自己的产品关键词排名更靠前&#xff0c;这样可以吸引更多的客户来点击浏览&#xff0c;从而获取到更多的流量与销量&#xff0c;但是要进行刷关键词是一个比较重大的工程&#xff0c;需要大量不同的买家号来进行操作&#xff0c;这时候就可以借用软件来…

亚马逊关键词应该如何选择?

为什么在 2022 年研究亚马逊关键词仍然是一项有价值的活动 你会认为&#xff0c;到目前为止&#xff0c;所有可能的产品细分市场都将在亚马逊上以某种形式或形式覆盖&#xff0c;但现实是&#xff0c;在这个庞大的生态系统中&#xff0c;亚马逊的产品一直在发生变化。 此外&am…

亚马逊关键词上首页怎么操作?

亚马逊关键词如果排在首页可以获得更多曝光&#xff0c;产品被购买的几率也更大。但是上首页也不是那么简单的&#xff0c;亚马逊关键词上首页怎么操作&#xff1f;操作上首页也是需要有规划的。 第一阶段 规划好想要刷的关键词&#xff0c;比如用什么样的长尾词购买刷单&…

亚马逊/关键词搜索挑战

亚马逊在全球有众多站点&#xff08;14个&#xff09;&#xff0c;在爬取搜索页面时&#xff0c;存在较多的挑战。为了方便大家沟通学习&#xff0c;现将我们在研发过程中的问题一一列举。对于具体的技术细节&#xff0c;可参考之前的文章亚马逊 - 关键字搜索 - 广告排名 - Cit…

亚马逊关键词上首页的方法有哪些?

关键词上首页一般是指在某个核心关键词搜索条件下的首页48个结果内&#xff0c;自己的产品排在前10的位置。分为两种情况。第一种是广告上首页&#xff0c;通过自动广告积累一定的买家搜索词数据&#xff0c;然后针对出现频率和转化相对较高的核心关键词进行精准投放。 第二种是…

亚马逊如何获得关键词

&#xff08;1&#xff09;从竞品中获取关键词 找到BSR排名靠前竞争对手的ASIN&#xff0c;从而通过排名页面或关键词搜索找到它们&#xff1b; 用与5个ASIN匹配的Amazon所有关键字&#xff1b; 查找具备以上ASIN同时转化率高的关键词&#xff1b;通过以上方法&#xff0c;你…

亚马逊运营人才必懂:亚马逊搜索词和关键词

即使是对亚马逊seo有一定经验的卖家有时也会混淆搜索词和关键IC的概念&#xff0c;两者都对seo有帮助&#xff0c;但是作用不同。下面海熹跨境人才网就来给大家详细介绍一下亚马逊搜索词和关键词&#xff0c;一起来了解一下吧。 I. 什么是亚马逊搜索词? 亚马逊搜索词(Search …

系统U盘制作随记

随身系统U盘制作 最近花了好多时间&#xff0c;废了好多U盘才把这东西搞明白了。 主要是自己的笔记本问题比较多&#xff0c;用实验室的Hp机一下就弄好了。 用这篇博客总结一下自己&#xff0c;然后附上详细的流程以免大家踩坑。 Windows to Go 这个比较容易上手 1. 准备…

软件版本号说明

1.版本命名规范 软件版本号有四部分组成&#xff0c;第一部分为主版本号&#xff0c;第二部分为次版本号&#xff0c;第三部分为修订版本号&#xff0c;第四部分为日期版本号加希腊字母版本号&#xff0c;希腊字母版本号共有五种&#xff0c;分别为base、alpha、beta 、RC 、 …

常见版本号说明

我们来看一下SpringCloud的版本信息,打开Spring官网,选择SpringCloudhttps://spring.io/projects/spring-cloud右侧显示了SpringCloud的版本,但是我们会发现,显示的版本信息,跟我们以往的目标软件信息是不一样的,我们回过来看SpirngBoothttps://spring.io/projects/spring-boot…

查看php项目tp版本,tp5.1如何查看版本号

ThinkPHP5.1在5.0的基础上对底层架构做了进一步的改进&#xff0c;引入新特性&#xff0c;并提升版本要求。另外一个事实是&#xff0c;5.1版本看起来对开发者更加友好&#xff0c;表现在目录结构更直观、调试输出更直观和代码提示更直观。 tp5.1如何查看版本号 查看文件&#…

查看各版本号

一、oracle服务器版本号 1 select* from v$version; 2 select * from product_component_version; 二、mysql服务器版本号 数据库中查询 1 select version(); 2 服务器端查询 mysql --version 三、linux操作系统版本号 1、查看当前操作系统内核信息 uname -a $ uname -a …