最近公司再做前后端分离得项目,我负责设计前后端分离得登录流程,由于是前后端分离,所以传统得登录信息存入session就不适用了,这个时候登录信息 页面交互信息应该怎么办呢?
我暂时想到一种

用redis存入登录信息具体操作如下

         1.流程图

2.账号信息存储以及数据格式
方案一.启动完之后查询数据库信息 初始化账号相关信息到redis
方案二.维护账号数据的时候同时修改redis账号信息数据
账号信息存储格式为 accinfo:账号的方式作为redis的key存储
例如:key为accinfo:zhangsan
value 类型为hash 里面的小key用账号作为小key
value 用json格式字符串来存储登陆人信息
例如:小key:zhangsan ,
value为
{“user_id”: “zhangsan”,
“name”: “张三”,
“age”: “20”,
“sex”: “1”,“code”: “132”}

3.前后台加密方式
1.前台动态salt获取(方案一) 输入账号密码之后提交前
调用后台接口同时存入redis 格式为salt:account 点击提交的时候 前台加密方式MD5(salt+md5(pwd)), 输入账号密码提交的之后根据账号 salt+account去获取动态salt,后台用同样的方式加密验证。

4.登录
1.登录接口
首先拿到账号去数据库查询是否存在?
不存在直接返回相关错误信息
GATEWAY_E_LOGIN_ACCOUNT_FAILED_CODE =”E_000244”
GATEWAY_E_LOGIN_ACCOUNT_FAILED_MSG=”Account_Not_Exist”

拿到该账号的密码(aes加密)之后的密码aespwd解密成pwd
MD5(salt+md5(pwd)); 得到passwordNow
和前台传来的加密数据password
不相等返回错误信息
GATEWAY_E_LOGIN_PASSWORD_FAILED_CODE =”E_000245”
GATEWAY_E_LOGIN_PASSWORD_FAILED_MSG=”Password_Mistake”

验证账号密码无误之后后台生成token返回给前台
并且把该token存入redis中并设置超时时间
存储格式为key为authToken:ip:token格式 例如authToken:192.168.0.9:2_7eba-db50-c9f4-351e-548b374_7
Value存账号如:zhangsan。
后台提供根据token获取用户信息接口。

5.登录失败返回信息(前台后台)

1.点击登录后台验证 如果账号不存在返回错误码暂定前台根据返回的错误码做相应的返回信息
code=”E_000244” msg=”Account_Not_Exist”

2.点击登录后台验证 如果密码验证不通过根据返回的错误码做相应的返回信息
code =”E_000245” msg=”Password_Mistake”

6.登录成功
前台将后台返回的token存入前台缓存(cookies或者其他缓存)
前台登录成功之后进入index页面
同时前台异步调用获取用户信息接口根据token获取登录账号信息。

7.前台接口调用
前台接口调用
所有的接口请求都需要将登录之后返回的token 放入header中传递过去key为GW_TOKEN value为token的值
后台处理所有请求之前需要验证ip+token是否合法有效
验证不通过返回对应的错误码前台返回登录页面
验证通过 直接重置当前token的失效时间并且返回response信息

获取动态盐接口
package com.dzq.processor.login;import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.dzq.base.annotation.Processor;
import com.dzq.base.helper.Md5Helper;
import com.dzq.base.helper.RedisHelper;
import com.dzq.base.localcache.Cache;
import com.dzq.base.log.Logger;
import com.dzq.base.log.LoggerFactory;
import com.dzq.base.protocols.Constants;
import com.dzq.base.protocols.ErrorConstants;
import com.dzq.dispatch.api.DispatchException;
import com.dzq.dispatch.api.IRequestProcessor;
import com.dzq.dispatch.api.ServiceRequest;
import com.dzq.dispatch.api.ServiceResponse;
import org.apache.commons.lang.RandomStringUtils;
import org.springframework.stereotype.Component;import java.util.concurrent.TimeUnit;/*** @Description 发布加密密码时的盐值, 盐值的长度为20, 格式为随机的字符和数字组合* 该值为动态数据,有效期 10秒,有效次数 1次* 输入数据:{"user_account":"zhangsan"} user_account: 用户登陆名* 输出数据:{"key":salt}* @Author chenlk*/
@Component
@Processor(Constants.OPT_WEBCORE_GET_SALT)
public class GetSaltProcessor implements IRequestProcessor {private static final Logger logger = LoggerFactory.getLogger(GetSaltProcessor.class);// 动态盐值的有效时间,默认 10 秒钟private static final Long saltExpire = 10000L;@Overridepublic void doProcess(ServiceRequest request, ServiceResponse response) {String userAccount = null;String pw = null;try {JSONObject jsonObject = JSON.parseObject(String.valueOf(request.getDefaultParam()));userAccount = jsonObject.getString("user_account");pw = jsonObject.getString("pw");if (userAccount == null || userAccount.equals("")) {response.setException(new DispatchException(ErrorConstants.GATE_E_LOGIN_INVALIDLOGINMSG_CODE,ErrorConstants.GATE_E_LOGIN_INVALIDLOGINMSG_MSG));logger.info(request.getRequestId(), request.getSystemId(), request.getOperation(),ErrorConstants.GATE_E_LOGIN_INVALIDLOGINMSG_MSG);return;}} catch (Exception e) {response.setException(new DispatchException(ErrorConstants.GATE_E_LOGIN_PARSELOGINMSG_EXCEPTION_CODE,ErrorConstants.GATE_E_LOGIN_PARSELOGINMSG_EXCEPTION_MSG));logger.error(request.getRequestId(), request.getSystemId(), request.getOperation(),"Parse login msg has exception.", e);return;}String salt = RandomStringUtils.randomAlphanumeric(20);if (pw != null) {logger.info(request.getRequestId(), request.getSystemId(), request.getOperation(),Md5Helper.encrypt(salt + Md5Helper.encrypt(pw)));}boolean redisCacheResult = false;try {RedisHelper.psetex(userAccount, salt, saltExpire);RedisHelper.psetex(salt, "false", saltExpire);redisCacheResult = true;} catch (Exception e) {redisCacheResult = false;logger.error(request.getRequestId(), request.getSystemId(), request.getOperation(),"Cache Salt into redis has exception.", e);}boolean localCacheResult = false;try {Cache.instance().putString(userAccount, salt, saltExpire, TimeUnit.MILLISECONDS);Cache.instance().putString(salt, "false", saltExpire, TimeUnit.MILLISECONDS);localCacheResult = true;} catch (Exception e) {localCacheResult = false;logger.error(request.getRequestId(), request.getSystemId(), request.getOperation(),"Cache Salt into local has exception.", e);}if (redisCacheResult == false && localCacheResult == false) {response.setException(new DispatchException(ErrorConstants.GATE_E_LOGIN_CACHESALT_EXCEPTION_CODE,ErrorConstants.GATE_E_LOGIN_CACHESALT_EXCEPTION_MSG));return;}JSONObject jsonObject = new JSONObject();jsonObject.put("key", salt);response.putDefaultResult(jsonObject);}@Overridepublic boolean validRequest(ServiceRequest request, ServiceResponse response) {return true;}
}#登录接口package com.dzq.processor.login;import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.dzq.base.annotation.Processor;
import com.dzq.base.helper.Md5Helper;
import com.dzq.base.helper.PropertiesHelper;
import com.dzq.base.helper.RedisHelper;
import com.dzq.base.localcache.Cache;
import com.dzq.base.log.Logger;
import com.dzq.base.log.LoggerFactory;
import com.dzq.base.protocols.Constants;
import com.dzq.base.protocols.ErrorConstants;
import com.dzq.dao.login.mapper.LoginMapper;
import com.dzq.dispatch.api.DispatchException;
import com.dzq.dispatch.api.IRequestProcessor;
import com.dzq.dispatch.api.ServiceRequest;
import com.dzq.dispatch.api.ServiceResponse;
import com.dzq.goalie.token.TokenRelease;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;/*** @Description 登陆流程处理器* pWord = md5(salt + md5(pwd))* 输入数据:{"user_account":"","pass_word":""}* @Author chenlk*/
@Component
@Processor(Constants.OPT_WEBCORE_LOGIN)
public class LoginProcessor implements IRequestProcessor {private static final Logger logger = LoggerFactory.getLogger(LoginProcessor.class);@AutowiredLoginMapper loginMapper;public Map<String, Object> accountInfo = null;@Overridepublic void doProcess(ServiceRequest request, ServiceResponse response) {String operationName = request.getOperation();String systemId = request.getSystemId();String requestId = request.getRequestId();String userAccount = "";String passWord = "";try {JSONObject jsonObject = JSON.parseObject(String.valueOf(request.getDefaultParam()));userAccount = jsonObject.getString("user_account");passWord = jsonObject.getString("pass_word");} catch (Exception e) {response.setException(new DispatchException(ErrorConstants.GATE_E_LOGIN_PARSELOGINMSG_EXCEPTION_CODE,ErrorConstants.GATE_E_LOGIN_PARSELOGINMSG_EXCEPTION_MSG));logger.error(request.getRequestId(), request.getSystemId(), request.getOperation(),"Parse login msg has exception.", e);return;}if (userAccount == null || userAccount.equals("") || passWord == null || passWord.equals("")) {response.setException(new DispatchException(ErrorConstants.GATE_E_LOGIN_INVALIDLOGINMSG_CODE,ErrorConstants.GATE_E_LOGIN_INVALIDLOGINMSG_MSG));logger.error(request.getRequestId(), request.getSystemId(), request.getOperation(),"UserName or passWord is empty.", null);return;}String salt = "";String isUse = "";/***盐值同时存在于redis和本地缓存* redis读取失败时,尝试读取本地缓存*/salt = RedisHelper.get(userAccount);if (salt != null && !salt.equals("")) {isUse = RedisHelper.get(salt);} else {try {salt = Cache.instance().getString(userAccount);isUse = Cache.instance().getString(salt);} catch (Exception e) {salt = null;isUse = null;}}/*** 盐值不存在或已过期* 盐值状态数据不存在或已过期*/if (salt == null || salt.equals("") || isUse == null || isUse.equals("")) {response.setException(new DispatchException(ErrorConstants.GATE_E_LOGIN_INVALIDSALTMSG_CODE,ErrorConstants.GATE_E_LOGIN_INVALIDSALTMSG_MSG));logger.error(request.getRequestId(), request.getSystemId(), request.getOperation(),"Salt(isUse) is expired.", null);return;}/*** 如果盐值和盐值状态数据都正常:* 1. 清空redis和本地缓存中的盐值数据* 2. 进行密码的验证* 3. 建立并保持登陆数据** 对于密码的验证,由于涉及到查询数据库,* 所以要及时进行用户ID、用户、密码的缓存,避免对数据库造成过多压力** 如果有个小黑暴力破解登陆流程怎么办呢?会不会出现这种情况呢?需不需对登陆流程进行加锁控制呢?*//*** step 1:* 清空redis和本地缓存中的盐值数据*/try {RedisHelper.delKey(userAccount);RedisHelper.delKey(salt);Cache.instance().delCache(userAccount);Cache.instance().delCache(salt);logger.info(request.getRequestId(), request.getSystemId(), request.getOperation(),"Clear the login data in the local cache and redis.");} catch (Exception e) {Cache.instance().delCache(userAccount);Cache.instance().delCache(salt);RedisHelper.delKey(userAccount);RedisHelper.delKey(salt);logger.error(request.getRequestId(), request.getSystemId(), request.getOperation(),"Clear the login data in the local cache and redis has exception.", e);}/*** step 2:* 进行密码的验证*/String redisPassWord = "";Boolean isLogin = false;try {/***  登录信息存在于redis*  redis读取失败时,查询数据库读取用户信息*/String redisAccountInfo = RedisHelper.hget(Constants.REDIS_PRELOAD_USERINFO + userAccount, "pass_word");if (redisAccountInfo != null && !"".equals(redisAccountInfo)) {redisPassWord = redisAccountInfo;} else {redisPassWord = getRedisPassWordByAccountInfo(request, response, userAccount);/*** 查询数据库读取用户信息* 查询无数据*/if (redisPassWord == null || redisPassWord.equals("")) {response.setException(new DispatchException(ErrorConstants.GATE_E_LOGIN_ACCOUNT_FAILED_CODE,ErrorConstants.GATE_E_LOGIN_ACCOUNT_FAILED_MSG));logger.error(request.getRequestId(), request.getSystemId(), request.getOperation(),"AccountInfo(isLogin) is expired.", null);return;}}// 加密 pWord = md5(salt + md5(pwd))String pWord = Md5Helper.encrypt(salt + redisPassWord);// TODO 待办事项  对接完成后需要放开注释// 验证通过登录设为true// if (passWord.equals(pWord)) {isLogin = true;// } else {//     response.setException(new DispatchException(//             ErrorConstants.GATEWAY_E_LOGIN_PASSWORD_FAILED_CODE,//             ErrorConstants.GATEWAY_E_LOGIN_PASSWORD_FAILED_MSG));//     logger.error(request.getRequestId(), request.getSystemId(), request.getOperation(),//             "Check passWord(isLogin) is Invalid.", null);//     return;// }} catch (Exception e) {response.setException(new DispatchException(ErrorConstants.GATEWAY_E_LOGIN_PASSWORD_EXCEPTION_CODE,ErrorConstants.GATEWAY_E_LOGIN_PASSWORD_EXCEPTION_MSG));logger.error(request.getRequestId(), request.getSystemId(), request.getOperation(),"Check passWord(isLogin) has exception.", e);}/*** step 3:* 建立并保持登陆数据*/try {if (isLogin) {HttpServletRequest hsRequest = null;hsRequest = (HttpServletRequest) request.getParam("httpServletRequest");TokenRelease.releaseToken(request, response, hsRequest, userAccount);logger.info(requestId, systemId, operationName,"LoginProcessor:login:SUCCESS.");}/*** step 4:* TODO 登录成功获取角色信息*/if (isLogin) {getRoleAuthInfobyAccount(request, response, userAccount, accountInfo);}} catch (Exception e) {response.setException(new DispatchException(ErrorConstants.GATEWAY_AUTH_TOKEN_EXCEPTION_CODE,ErrorConstants.GATEWAY_AUTH_TOKEN_EXCEPTION_MSG));logger.error(request.getRequestId(), request.getSystemId(), request.getOperation(),"Create AuthToken has exception.", e);}}@Overridepublic boolean validRequest(ServiceRequest request, ServiceResponse response) {return true;}/*** @param request* @param response* @param userAccount* @return* @Description 获取密码*/public String getRedisPassWordByAccountInfo(ServiceRequest request, ServiceResponse response, String userAccount) {String redisPassWord = null;try {accountInfo = loginMapper.queryAccountInfoByUserId(userAccount);if (accountInfo != null) {redisPassWord = accountInfo.get("pass_word") == null ? "" : accountInfo.get("pass_word").toString();}} catch (Exception e) {redisPassWord = null;}return redisPassWord;}/*** 获取权限信息** @param request* @param response* @param userAccount* @return*/public void getRoleAuthInfobyAccount(ServiceRequest request, ServiceResponse response, String userAccount, Map<String, Object> accountInfo) {try {String preJsonRoleList = RedisHelper.hget(Constants.REDIS_PRELOAD_USERINFO + userAccount, "roleList");String preJsonUserInfo = RedisHelper.hget(Constants.REDIS_PRELOAD_USERINFO + userAccount, userAccount);String jsonRoleList = RedisHelper.hget(Constants.REDIS_ACCINFO + userAccount, "roleList");String jsonUserInfo = RedisHelper.hget(Constants.REDIS_ACCINFO + userAccount, userAccount);String now_role_id = "-1";Boolean flag = false;HashMap redisMap = new HashMap();if (accountInfo != null) {String orgid = accountInfo.get("orgid") == null ? "" : accountInfo.get("orgid").toString();// 角色信息List<HashMap<String, Object>> userRoleList = loginMapper.queryRoleListByUserId(userAccount);List<Map<String, Object>> jsonUserRoleList = new ArrayList<Map<String, Object>>();if (userRoleList != null && userRoleList.size() > 0) {for (HashMap<String, Object> userRoleInfo : userRoleList) {String role_id = userRoleInfo.get("role_id") == null ? "" : userRoleInfo.get("role_id").toString();String role_name = userRoleInfo.get("role_name") == null ? "" : userRoleInfo.get("role_name").toString();String role_type = userRoleInfo.get("role_type") == null ? "" : userRoleInfo.get("role_type").toString();if (!flag) {now_role_id = role_id;flag = true;}Map<String, Object> userRoleMap = new HashMap<>();userRoleMap.put("role_id", role_id);userRoleMap.put("role_name", role_name);userRoleMap.put("role_type", role_type);jsonUserRoleList.add(userRoleMap);}}String jsonUserRole = JSONObject.toJSONString(jsonUserRoleList);if (jsonUserRoleList != null && jsonUserRoleList.size() > 0) {redisMap.put("roleList", jsonUserRole);}if (orgid != null) {accountInfo.put("is_system_user", "1");} else {accountInfo.put("is_system_user", "0");String operator_id = accountInfo.get("operator_id") == null ? "-1" : accountInfo.get("operator_id").toString();// HashMap<String, Object> roleInfo = loginMapper.queryRoleInfoByOperatorId(operator_id);// now_role_id = roleInfo.get("role_id") == null ? "-1" : roleInfo.get("role_id").toString();accountInfo.put("now_role_id", now_role_id);}String redisPassWord = accountInfo.get("pass_word") == null ? "" : accountInfo.get("pass_word").toString();redisMap.put("pass_word", redisPassWord);accountInfo.remove("pass_word");redisMap.put(userAccount, JSON.toJSON(accountInfo).toString());RedisHelper.hset(Constants.REDIS_ACCINFO + userAccount, redisMap);RedisHelper.expire(Constants.REDIS_ACCINFO + userAccount, PropertiesHelper.getLongValue("gateway.login.expire"));} else {if (preJsonUserInfo != null && (jsonUserInfo == null || "".equals(jsonUserInfo))) {redisMap.put(userAccount, JSON.toJSON(preJsonUserInfo).toString());// RedisHelper.hset(Constants.REDIS_ACCINFO + userAccount, userAccount, jsonUserInfo);}if (preJsonRoleList != null && (jsonRoleList == null || "".equals(jsonRoleList))) {redisMap.put("roleList", preJsonRoleList);// RedisHelper.hset(Constants.REDIS_ACCINFO + userAccount, "roleList", preJsonRoleList);}RedisHelper.hset(Constants.REDIS_ACCINFO + userAccount, redisMap);RedisHelper.expire(Constants.REDIS_ACCINFO + userAccount, PropertiesHelper.getLongValue("gateway.login.expire"));}} catch (Exception e) {response.setException(new DispatchException(ErrorConstants.GATEWAY_E_QUERY_USERROLE_EXCEPTION_CODE,ErrorConstants.GATEWAY_E_QUERY_USERROLE_EXCEPTION_MSG));logger.error(request.getRequestId(), request.getSystemId(), request.getOperation(),"get getRoleAuthInfobyAccount has exception.", e);}}/*** 重新刷新登录信息数据** @param request* @param response* @param userAccount* @param loginMapper*/public static void flushRoleAuthInfobyAccount(ServiceRequest request, ServiceResponse response, String userAccount, LoginMapper loginMapper) {if (loginMapper != null) {Map<String, Object> accountInfo = loginMapper.queryAccountInfoByUserId(userAccount);getRoleAuthInfobyAccount(request, response, userAccount, accountInfo, loginMapper);}}/*** 获取权限信息** @param request* @param response* @param userAccount* @return*/public static void getRoleAuthInfobyAccount(ServiceRequest request, ServiceResponse response, String userAccount, Map<String, Object> accountInfo, LoginMapper loginMapper) {try {String preJsonRoleList = RedisHelper.hget(Constants.REDIS_PRELOAD_USERINFO + userAccount, "roleList");String preJsonUserInfo = RedisHelper.hget(Constants.REDIS_PRELOAD_USERINFO + userAccount, userAccount);String jsonRoleList = RedisHelper.hget(Constants.REDIS_ACCINFO + userAccount, "roleList");String jsonUserInfo = RedisHelper.hget(Constants.REDIS_ACCINFO + userAccount, userAccount);String now_role_id = "-1";Boolean flag = false;HashMap redisMap = new HashMap();if (accountInfo != null) {String orgid = accountInfo.get("orgid") == null ? "" : accountInfo.get("orgid").toString();// 角色信息List<HashMap<String, Object>> userRoleList = loginMapper.queryRoleListByUserId(userAccount);List<Map<String, Object>> jsonUserRoleList = new ArrayList<Map<String, Object>>();if (userRoleList != null && userRoleList.size() > 0) {for (HashMap<String, Object> userRoleInfo : userRoleList) {String role_id = userRoleInfo.get("role_id") == null ? "" : userRoleInfo.get("role_id").toString();String role_name = userRoleInfo.get("role_name") == null ? "" : userRoleInfo.get("role_name").toString();String role_type = userRoleInfo.get("role_type") == null ? "" : userRoleInfo.get("role_type").toString();if (!flag) {now_role_id = role_id;flag = true;}Map<String, Object> userRoleMap = new HashMap<>();userRoleMap.put("role_id", role_id);userRoleMap.put("role_name", role_name);userRoleMap.put("role_type", role_type);jsonUserRoleList.add(userRoleMap);}}String jsonUserRole = JSONObject.toJSONString(jsonUserRoleList);if (jsonUserRoleList != null && jsonUserRoleList.size() > 0) {redisMap.put("roleList", jsonUserRole);}if (orgid != null) {accountInfo.put("is_system_user", "1");} else {accountInfo.put("is_system_user", "0");String operator_id = accountInfo.get("operator_id") == null ? "-1" : accountInfo.get("operator_id").toString();// HashMap<String, Object> roleInfo = loginMapper.queryRoleInfoByOperatorId(operator_id);// now_role_id = roleInfo.get("role_id") == null ? "-1" : roleInfo.get("role_id").toString();accountInfo.put("now_role_id", now_role_id);}String redisPassWord = accountInfo.get("pass_word") == null ? "" : accountInfo.get("pass_word").toString();redisMap.put("pass_word", redisPassWord);accountInfo.remove("pass_word");redisMap.put(userAccount, JSON.toJSON(accountInfo).toString());RedisHelper.hset(Constants.REDIS_ACCINFO + userAccount, redisMap);RedisHelper.expire(Constants.REDIS_ACCINFO + userAccount, PropertiesHelper.getLongValue("gateway.login.expire"));} else {if (preJsonUserInfo != null && (jsonUserInfo == null || "".equals(jsonUserInfo))) {redisMap.put(userAccount, JSON.toJSON(preJsonUserInfo).toString());// RedisHelper.hset(Constants.REDIS_ACCINFO + userAccount, userAccount, jsonUserInfo);}if (preJsonRoleList != null && (jsonRoleList == null || "".equals(jsonRoleList))) {redisMap.put("roleList", preJsonRoleList);// RedisHelper.hset(Constants.REDIS_ACCINFO + userAccount, "roleList", preJsonRoleList);}RedisHelper.hset(Constants.REDIS_ACCINFO + userAccount, redisMap);RedisHelper.expire(Constants.REDIS_ACCINFO + userAccount, PropertiesHelper.getLongValue("gateway.login.expire"));}} catch (Exception e) {response.setException(new DispatchException(ErrorConstants.GATEWAY_E_QUERY_USERINFO_EXCEPTION_CODE,ErrorConstants.GATEWAY_E_QUERY_USERINFO_EXCEPTION_MSG));logger.error(request.getRequestId(), request.getSystemId(), request.getOperation(),"userInfo get getRoleAuthInfobyAccount has exception.", e);}}public static List<?> parseJsonToArray(String json, Class<?> clazz) {List<?> gameList = JSONObject.parseArray(json, clazz);return gameList;}public static void main(String[] args) {System.out.println(Boolean.valueOf(""));}
}token发布
package com.dzq.goalie.token;import com.alibaba.fastjson.JSONObject;
import com.dzq.base.helper.IpAdressHelper;
import com.dzq.base.helper.PropertiesHelper;
import com.dzq.base.helper.RedisHelper;
import com.dzq.base.log.Logger;
import com.dzq.base.log.LoggerFactory;
import com.dzq.base.protocols.Constants;
import com.dzq.dispatch.api.ServiceRequest;
import com.dzq.dispatch.api.ServiceResponse;
import org.springframework.stereotype.Component;import javax.servlet.http.HttpServletRequest;
import java.util.Calendar;
import java.util.UUID;/*** @Description token 发布* @Author slg*/
@Component
public class TokenRelease {private static final Logger logger = LoggerFactory.getLogger(TokenRelease.class);/*** 发布 token** @param request* @param response*/public static void releaseToken(ServiceRequest request, ServiceResponse response, HttpServletRequest req, String account) {/*** 通过当前毫秒数,获取UUID*/String token = UUID.randomUUID().toString().substring(2, 23);//String expire = System.currentTimeMillis() + "";// 对token添加特殊混淆Calendar cal = Calendar.getInstance();String salt = Constants.GATEWAY_TOKEN_SALT[cal.get(Calendar.DAY_OF_WEEK) - 1];String salt_start = salt.split(",")[0];String salt_end = salt.split(",")[1];token = salt_start + token + salt_end;String ip = "";if (req != null) {ip = IpAdressHelper.getRemoteAddr(req);} else {ip = "127.0.0.1";}/*** 将token存入redis格式ip+token,value为当前时间毫秒数* 并返回token* {"token":""}*/RedisHelper.psetex(Constants.AUTH_TOKEN + ip + ":" + token, account, PropertiesHelper.getLongValue("gateway.token.expire"));JSONObject jsonObject = new JSONObject();jsonObject.put("token", token);response.setRetCode(Constants.GATEWAY_HTTP_SUCCESS_CODE);response.setRetMsg(Constants.GATEWAY_HTTP_SUCCESS_MSG);response.putDefaultResult(jsonObject);}
}token验证
package com.dzq.goalie.token;import com.dzq.base.helper.IpAdressHelper;
import com.dzq.base.helper.PropertiesHelper;
import com.dzq.base.helper.RedisHelper;
import com.dzq.base.log.Logger;
import com.dzq.base.log.LoggerFactory;
import com.dzq.base.protocols.Constants;
import com.dzq.base.protocols.ErrorConstants;
import com.dzq.dispatch.api.ServiceRequest;
import com.dzq.dispatch.api.ServiceResponse;
import org.springframework.stereotype.Component;import javax.servlet.http.HttpServletRequest;/*** @Description token 验证* @Author*/
@Component
public class TokenVerify {private static final Logger logger = LoggerFactory.getLogger(TokenRelease.class);/*** 统一token校验** @param request* @param response* @return*/public static boolean tokenVerify(ServiceRequest request, ServiceResponse response) {/*** token验证包括:有效性、有效期、接口访问权等* 有效性验证方式为:判断redis是否存在该key* 有效期验证方式为:判断redis中value的时间戳是否超时* 接口访问权验证方式为:暂时跳过** {"requestID":"","operation":"","token":"","requestTime":""}*/HttpServletRequest req = (HttpServletRequest) request.getDefaultParam();String token = req.getHeader(Constants.GATEWAY_HTTP_HEADER_TOKEN);String referer = req.getHeader("referer");if (token == null) {response.setRetCode(ErrorConstants.GATEWAY_AUTH_TOKEN_NO_TRANSMIT_CODE);response.setRetMsg(ErrorConstants.GATEWAY_AUTH_TOKEN_NO_TRANSMIT_MSG);return false;}/*** Step 1:* 判断token是否存在redis中* tokenValue 为发布时的毫秒数*/String ip = IpAdressHelper.getRemoteAddr(req);String tokenValue = RedisHelper.get(Constants.AUTH_TOKEN + ip + ":" + token);if (tokenValue == null || tokenValue.equals("")) {response.setRetCode(ErrorConstants.GATEWAY_AUTH_TOKEN_NO_EXIST_CODE);response.setRetMsg(ErrorConstants.GATEWAY_AUTH_TOKEN_NO_EXIST_MSG);return false;}//重置过期时间RedisHelper.expire(Constants.AUTH_TOKEN + ip + ":" + token, PropertiesHelper.getLongValue("gateway.token.expire"));return true;}
}

【前后端分离登录流程】相关推荐

  1. Springboot + Spring Security 实现前后端分离登录认证及权限控制

    Spring Security简介 Spring Security 是 Spring 家族中的一个安全管理框架,实际上,在 Spring Boot 出现之前,Spring Security 就已经发展 ...

  2. php前后端分离登录,前后端分离下如何登录

    1 Web登录涉及到知识点 1.1 HTTP无状态性HTTP是无状态的,一次请求结束,连接断开,下次服务器再收到请求,它就不知道这个请求是哪个用户发过来的.当然它知道是哪个客户端地址发过来的,但是对于 ...

  3. Java Spring boot element ui activiti前后端分离,流程审批,权限管理框架

    基于react ant design pro typescript 技术框架已经重磅推出 预览地址 系统介绍 是什么? 使用springboot,activiti,mybatis,vue elemen ...

  4. html密码验证 并跳转页面,vuejs 实现前后端分离登录验证和页面自动跳转

    使用的技术点: vue-router axios vuex element-ui qs 项目介绍: 这个项目是一个类似google相册功能的项目,目前实现的是图片特征提取,可以以图搜图,最终打造成一个 ...

  5. Spring-Security 实现前后端分离登录

    简述 使用Spring-Security来实现登录,但是搜到的都是通过模板引擎的方式来实现的,也就是必须通过login.html页面来登录.考虑到现在架构都是采用的是动静分离的架构,那么登录也需要使用 ...

  6. SpringSecurity前后端分离登录认证

    文章总结自三更草堂SpringSecurity框架教程,个人认为是B站最好用的Security+JWT讲解. 1. 项目搭建 1.1 新建SpringBoot项目 SpringBoot使用的是2.7. ...

  7. springboot-vue前后端分离登录

    目录 1 权限系统: 2  完成登录 2.1 前端布局 2.2 完成后端登录接口 3 登录的bug 1 权限系统: 1.前端使用: vue + elementui + axios + css + ht ...

  8. 基于Jeecgboot前后端分离的流程管理平台演示系统安装(二)

    三.手动发布与测试 后端: 修改application-prod.yml文件,根据自己的发布机器的相关参数进行修改,再进行编译,处出来nbcio-boot\nbcio-boot-module-syst ...

  9. Springboot+JWT+SpringSecurity+Vue+Redis 前后端分离登录(1后端)

    java 后端跨域配置 @Configuration public class CorsConfig {@Beanpublic CorsFilter corsFilter() {final UrlBa ...

最新文章

  1. JVM 老年代对象来源
  2. 几款不同颜色LED的伏安特性
  3. hibernate教程--快速入门(增删改查)
  4. Boost:BOOST_ASSERT用法的测试程序
  5. servlet中弹出网页对话框
  6. 【APICloud系列|33】移动应用软件加固步骤,适合所有的安卓应用市场
  7. 计算机策划知识竞赛有创意的主题,【社团活动】首届创意·科技文化节--第八届计算机趣味知识竞赛决赛...
  8. 互站卖的分发美化版可以封装双端APP
  9. 链表合并面试100题系列之18链表合并
  10. MySQL增量备份及恢复
  11. js setInterval() 用法示例
  12. SQL基本语句1——创建、添加、删除
  13. linux打开九针串口,RS232 9针串口定义
  14. 算法 思维导图(一)
  15. 免费的开源飞行规划软件Little Navmap
  16. 服务器怎么建立无线局域网,家庭无线局域网的组建教程
  17. 2011 我们的七夕
  18. 第二次作业:微信实例分析
  19. ExcelToMySQL-批量导入Excel文件到MySQL数据库的自动化工具
  20. 连接手表_小米手表体验报告(上)

热门文章

  1. C语言 习题3-1 比较大小 (简单解法)
  2. android 文件编辑,文件编辑软件(在线文档编辑)
  3. 《大话物联网(第2版)》赠书活动名单公告
  4. 无力回天...机关算尽,还是死在上线之中.............
  5. 双层pdf-不用手动添加目录超链接教程
  6. 自问自答学ArrayList,看这篇就够了,详解问答
  7. Rational Rose使用说明
  8. lol-----寒冰射手-----艾希
  9. 优课在线 实境英语作业3Unit 11-15
  10. Mac电脑访问不了正常URL