十年網(wǎng)站開(kāi)發(fā)經(jīng)驗(yàn) + 多家企業(yè)客戶 + 靠譜的建站團(tuán)隊(duì)
量身定制 + 運(yùn)營(yíng)維護(hù)+專業(yè)推廣+無(wú)憂售后,網(wǎng)站問(wèn)題一站解決
一、需求
“專業(yè)、務(wù)實(shí)、高效、創(chuàng)新、把客戶的事當(dāng)成自己的事”是我們每一個(gè)人一直以來(lái)堅(jiān)持追求的企業(yè)文化。 成都創(chuàng)新互聯(lián)公司是您可以信賴的網(wǎng)站建設(shè)服務(wù)商、專業(yè)的互聯(lián)網(wǎng)服務(wù)提供商! 專注于成都網(wǎng)站設(shè)計(jì)、成都網(wǎng)站建設(shè)、軟件開(kāi)發(fā)、設(shè)計(jì)服務(wù)業(yè)務(wù)。我們始終堅(jiān)持以客戶需求為導(dǎo)向,結(jié)合用戶體驗(yàn)與視覺(jué)傳達(dá),提供有針對(duì)性的項(xiàng)目解決方案,提供專業(yè)性的建議,創(chuàng)新互聯(lián)建站將不斷地超越自我,追逐市場(chǎng),引領(lǐng)市場(chǎng)!
實(shí)現(xiàn)用戶在瀏覽器登錄后,跳轉(zhuǎn)到其他頁(yè)面,當(dāng)用戶在其它地方又登錄時(shí),前面用戶登錄的頁(yè)面退出登錄(列如qq擠號(hào)那種方式)
二、實(shí)現(xiàn)思路
用戶在前端填寫(xiě)用戶信息登錄后,后臺(tái)接收數(shù)據(jù)先去數(shù)據(jù)庫(kù)進(jìn)行判斷,如果登錄成功,創(chuàng)建map集合,以用戶id為鍵,token為值,先通過(guò)當(dāng)前登錄用戶的id去獲取token,如果token存在說(shuō)明該用戶已經(jīng)登錄過(guò),調(diào)用redis以token為鍵刪除上個(gè)用戶的信息,調(diào)用方法生成新token,并將token存入map集合,將用戶信息存入redis,并將token存入cookie。當(dāng)用戶回到前面登錄的頁(yè)面時(shí),刷新頁(yè)面,調(diào)用方法,通過(guò)后端獲取cookie的token值,通過(guò)token在redis中查詢用戶信息是否存在,如果不存在,前端通過(guò)返回值判斷重新回到登錄頁(yè)面!
三、實(shí)現(xiàn)代碼
后端:
1、創(chuàng)建SpringBoot項(xiàng)目,創(chuàng)建User表,由于是通過(guò)Vue編寫(xiě)的,所以是前后端分離,需要跨域,我這里編寫(xiě)了跨域配置類,還有redis的util類,返回的封裝類,cookie的util類,文末有源碼提供,可以自行提取。
2、yum配置文件
spring: redis: database: 0 #redis的默認(rèn)數(shù)據(jù)庫(kù)為0 host: 127.0.0.1 #鏈接redis的ip port: 6379 #鏈接redis的端口號(hào) password: #鏈接redis的密碼 默認(rèn)為空 jedis: pool: max-total: 200 #鏈接redis的總數(shù)目 max-active: 100 #鏈接redis的最大 max-idle: 8 #最大的鏈接數(shù)量 min-idle: 5 #最小的鏈接數(shù)量 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: true server: port: 8888 REDIS_KEY : USER_TOKEN
3、編寫(xiě)實(shí)體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、編寫(xiě)Dao,UserDao.class
public interface UserDao extends JpaRepository{ public User findByUsernameAndPassword(String username, String password); }
5、編寫(xiě)serviceImpl,UserServiceImpl.class進(jìn)行登錄的業(yè)務(wù)邏輯處理
@Service public class UserServiceImpl{ @Autowired private UserDao userDao; @Autowired private JedisDao jedisDao; @Value("${REDIS_KEY}") //從配置文件中取值 private String KEY; private MapUserLogin = 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、編寫(xiě)controller,接收前端請(qǐng)求,返回?cái)?shù)據(jù)
@RestController public 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("用戶名或密碼錯(cuò)誤!"); return responseResult; } }catch (Exception e) { responseResult.setState(500); responseResult.setMsg("發(fā)生錯(cuò)誤,登錄失敗!"); 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("發(fā)生錯(cuò)誤!"); return responseResult; } } }
Vue前端
1、創(chuàng)建Vue項(xiàng)目:vue init webpack 項(xiàng)目名稱
2、引入axios:npm install --save axios vue-axios
3、引入element:npm i element-ui -S
4、在src的main.js下配置
import axios from 'axios' import VueAxios from 'vue-axios' // element-ui 引入文件 import ElementUI from 'element-ui' import 'element-ui/lib/theme-chalk/index.css' //注冊(cè) VueAxios, axios Vue.use(VueAxios, axios) Vue.use(ElementUI) //配置axios支持cookie axios.defaults.withCredentials = true;
5、在src的components下創(chuàng)建login.vue,userinfo.vue,并在src的router下配置訪問(wèn)地址
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、前端的代碼這里就不貼出了,代碼是有詳細(xì)的注釋,請(qǐng)自行下載代碼查看
四、代碼地址和演示效果
登錄:
下線:
dome代碼地址
鏈接: https://pan.baidu.com/s/1rXU46LCLpMxDzVEV_CpqFw
提取碼: yquh
總結(jié)
以上所述是小編給大家介紹的SpringBoot+Vue+Redis實(shí)現(xiàn)單點(diǎn)登錄(一處登錄另一處退出登錄),希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)創(chuàng)新互聯(lián)網(wǎng)站的支持!
如果你覺(jué)得本文對(duì)你有幫助,歡迎轉(zhuǎn)載,煩請(qǐng)注明出處,謝謝!