先分析一下登录的时候要干什么首先要弄清楚要干什么。登录后,系统就会知道这是谁,他有什么权限,可以给他开放哪些业务功能,可以看到哪些菜单?...这就是这个函数存在的目的和意义。如何实施?如何实现?用什么来实现的?我们的项目是Springboot+Vue前端分离型。选择使用token+redis来实现,权限使用SpringSecurity。前后端分离不可避免的问题之一就是单点登录。单点登录我们有很多实现方式:CAS中心认证、JWT、token等。我们的方式其实是基于token的单点登录实现。对于单点登录,改天再整理一篇关于OAuth2.0的实现的文章,今天就不做了。上面代码的概念越来越神秘了。让我们直接上代码。接口:@PostMapping("/login")publicAjaxResultlogin(@RequestBodyLoginBodyloginBody){AjaxResultajax=AjaxResult.success();//生成token//用户名、密码、验证码、uuidStringtoken=loginService.登录(loginBody.getUsername(),loginBody.getPassword(),loginBody.getCode(),ajax.put(Constants.TOKEN,token);spring复制用户信息返回ajax;/**登录验证*/publicStringlogin(Stringusername,Stringpassword,Stringcode,Stringuuid){//验证码开关,顺便把系统配置相关的开关缓存在redis中,系统启动时间到载入。这段代码不会发布booleancaptchaEnabled=configService.selectCaptchaEnabled();if(captchaEnabled){//uuid是验证码的rediskey,是登录页面加载时验证码生成接口返回的validateCaptcha(username,code,uuid);}//用户验证--SpringSecurityAuthenticationauthentication=null;尝试{UsernamePasswordAuthenticationTokenauthenticationToken=newUsernamePasswordAuthenticationToken(用户名,密码);AuthenticationContextHolder.setContext(authenticationToken);//该方法会去调用UserDetailsS??erviceImpl.loadUserByUsername。//authentication=authenticationManager.authenticate(authenticationToken);}catch(Exceptione){if(einstanceofBadCredentialsException){AsyncManager.me().execute(AsyncFactory.recordLogininfor(username,Constants.LOGIN_FAIL,MessageUtils.message("user.password.not.match")));抛出新的UserPasswordNotMatchException();}else{AsyncManager.me().execute(AsyncFactory.recordLogininfor(username,Constants.LOGIN_FAIL,e.getMessage()));抛出新的ServiceException(e.getMessage());}}最后{AuthenticationContextHolder.clearContext();}AsyncManager.me().execute(AsyncFactory.recordLogininfor(username,Constants.LOGIN_SUCCESS,MessageUtils.message("user.login.success")));LoginUserloginUser=(LoginUser)authentication.getPrincipal();recordLoginInfo(loginUser.getUserId());//生成tokenreturntokenService.createToken(loginUser);}复制代码,粘贴验证验证码的部分,看看大概的逻辑(这段代码太破..不全出来)/**Verification验证码*/publicvoidvalidateCaptcha(Stringusername,Stringcode,Stringuuid){//uuid是验证码的rediskeyStringverifyKey=CacheConstants.CAPTCHA_CODE_KEY+StringUtils.nvl(uuid,"");//字符串CAPTCHA_CODE_KEY="captcha_codes:";Stringcaptcha=redisCache.getCacheObject(verifyKey);redisCache.deleteObject(verifyKey);if(captcha==null){AsyncManager.me().execute(AsyncFactory.record(username,Constants.LOGIN_FAIL,MessageUtils.message("user.jcaptcha.expire")));抛出新的CaptchaExpireException();}if(!code.equalsIgnoreCase(captcha)){AsyncManager.me().execute(AsyncFactory.recordLogininfor(username,Constants.LOGIN_FAIL,MessageUtils.message("user.jcaptcha.error")));抛出新的CaptchaException();}}在此处复制代码令牌生成部分,token/**createtoken*/publicStringcreateToken(LoginUserloginUser){Stringtoken=IdUtils.fastUUID();loginUser.setToken(令牌);setUserAgent(登录用户);refreshToken(loginUser);Map