时间:2021-05-20
一、需求
实现用户在浏览器登录后,跳转到其他页面,当用户在其它地方又登录时,前面用户登录的页面退出登录(列如qq挤号那种方式)
二、实现思路
用户在前端填写用户信息登录后,后台接收数据先去数据库进行判断,如果登录成功,创建map集合,以用户id为键,token为值,先通过当前登录用户的id去获取token,如果token存在说明该用户已经登录过,调用redis以token为键删除上个用户的信息,调用方法生成新token,并将token存入map集合,将用户信息存入redis,并将token存入cookie。当用户回到前面登录的页面时,刷新页面,调用方法,通过后端获取cookie的token值,通过token在redis中查询用户信息是否存在,如果不存在,前端通过返回值判断重新回到登录页面!
三、实现代码
后端:
1、创建SpringBoot项目,创建User表,由于是通过Vue编写的,所以是前后端分离,需要跨域,我这里编写了跨域配置类,还有redis的util类,返回的封装类,cookie的util类,文末有源码提供,可以自行提取。
2、yum配置文件
spring: redis: database: 0 #redis的默认数据库为0 host: 127.0.0.1 #链接redis的ip port: 6379 #链接redis的端口号 password: #链接redis的密码 默认为空 jedis: pool: max-total: 200 #链接redis的总数目 max-active: 100 #链接redis的最大 max-idle: 8 #最大的链接数量 min-idle: 5 #最小的链接数量 datasource: url: jdbc:mysql://127.0.0.1:3306/test?useUnicode=true username: root password: root driver-class-name: com.mysql.jdbc.Driver jpa: show-sql: trueserver: port: 8888REDIS_KEY : USER_TOKEN3、编写实体User.class
@Data@Entity@Table(name = "user")public class User { @Id @Column(name = "id",unique = true,nullable = false) private int id; @Column(name = "username",nullable = false) private String username; @Column(name = "password",nullable = false) private String password;}4、编写Dao,UserDao.class
public interface UserDao extends JpaRepository<User,Integer> { public User findByUsernameAndPassword(String username, String password);}5、编写serviceImpl,UserServiceImpl.class进行登录的业务逻辑处理
@Servicepublic class UserServiceImpl{ @Autowired private UserDao userDao; @Autowired private JedisDao jedisDao; @Value("${REDIS_KEY}") //从配置文件中取值 private String KEY; private Map<Integer,String> UserLogin = new HashMap<>(); /** * 登录 * @param request * @param response * @param u * @return */ public User userlogin(HttpServletRequest request, HttpServletResponse response, User u){ //查询登录是否成功 User user=userDao.findByUsernameAndPassword(u.getUsername(),u.getPassword()); //判断us是否为空 if(user==null){ return null; } //生成token String token="user_"+ UUID.randomUUID().toString(); //从map中获得redis中的key String oldToken = UserLogin.get(user.getId()); //判断map中是否存在该id if(!StringUtils.isEmpty(oldToken)){ //删除redis中老的值 jedisDao.delValue(oldToken); } //将新的的key保存到map中 UserLogin.put(user.getId(),token); //将信息存入redis jedisDao.setValue(token, JsonUtils.objectToJson(user)); //将token放入cookie中 CookieUtils.setCookie(request,response,KEY,token,5*60,true); return user; } /** * 判断是否登录 * @param response * @param request * @return */ public String getUserByToken(HttpServletResponse response, HttpServletRequest request) { //从cookie中取出用户token String token=CookieUtils.getCookieValue(request,KEY); //从redis中取出用户信息 String user= jedisDao.getValue(token); return user; }}6、编写controller,接收前端请求,返回数据
@RestControllerpublic class LoginController { @Autowired private UserServiceImpl userService; /** * 登录 * @param response * @param request * @param user * @param model * @return */ @PostMapping("/login") public ResponseResult Login(HttpServletResponse response , HttpServletRequest request, @RequestBody User user, Model model){ ResponseResult responseResult=new ResponseResult(); try { User user2 = userService.userlogin(request, response, user); if (user2!=null){ responseResult.setState(200); responseResult.setMsg("登录成功!"); return responseResult; }else{ responseResult.setState(202); responseResult.setMsg("用户名或密码错误!"); return responseResult; } }catch (Exception e) { responseResult.setState(500); responseResult.setMsg("发生错误,登录失败!"); return responseResult; } } /** * 判断是否登录 * @param response * @param request * @return * @throws Exception */ @GetMapping("/toLogin") public ResponseResult getUserInfo(HttpServletResponse response , HttpServletRequest request) throws Exception { ResponseResult responseResult=new ResponseResult(); try{ String token = userService.getUserByToken(response, request); if(token!=null){ responseResult.setState(200); responseResult.setMsg("登录中!"); return responseResult; }else{ responseResult.setState(202); responseResult.setMsg("在别处登录!"); return responseResult; } }catch (Exception e){ response.setStatus(500); responseResult.setMsg("发生错误!"); return responseResult; } }}Vue前端
1、创建Vue项目:vue init webpack 项目名称
2、引入axios:npm install --save axios vue-axios
3、引入element:npm i element-ui -S
4、在src的main.js下配置
5、在src的components下创建login.vue,userinfo.vue,并在src的router下配置访问地址
import Vue from 'vue'import Router from 'vue-router'import login from '@/components/login'import UserInfo from '@/components/userinfo'Vue.use(Router)export default new Router({ routes: [{ path: '/login', component: login }, { path: '/user_info', component: UserInfo }]})6、前端的代码这里就不贴出了,代码是有详细的注释,请自行下载代码查看
四、代码地址和演示效果
登录:
下线:
dome代码地址
链接: https://pan.baidu.com/s/1rXU46LCLpMxDzVEV_CpqFw
提取码: yquh
总结
以上所述是小编给大家介绍的SpringBoot+Vue+Redis实现单点登录(一处登录另一处退出登录),希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
什么是单点登录?我想肯定有一部分人“望文生义”的认为单点登录就是一个用户只能在一处登录,其实这是错误的理解(我记得我第一次也是这么理解的)。单点登录指的是多个子
本文主要介绍了SpringSecurityOAuth2实现登录互踢的示例代码,分享给大家,具体如下:背景说明一个账号只能一处登录,类似的业务需求在现有后管类系统
vue官方推荐使用axios发送请求首先上需求1.需要封装全局调用2.返回一个promise对象3.错误全局统一处理4.除了登录界面token带入头部5.登录时
在SpringBoot项目中,异常统一处理,可以使用Spring中@ControllerAdvice来统一处理,也可以自己来定义异常处理方案。SpringBoo
用语言实现好处:1、可以减少对数据库的访问。2、可移植性好。坏处:1、操作起来考虑的东西较多,修改一处就要修改别一处。也就是说是相互关联的。如果少改了某一处,很