生活随笔
收集整理的這篇文章主要介紹了
基于token身份认证的完整实例
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
文章目錄
- 前言
- 一、基于Token的身份認證工作流程
- 二、實現步驟
- 1.配置過濾請求
- 2.實現過濾器
- 3.登錄接口
- 4.登錄之后獲取用戶信息
- 總結
前言
基于Token的身份認證是無狀態的,服務器或者Session中不會存儲任何用戶信息。
一、基于Token的身份認證工作流程
1.用戶通過用戶名和密碼請求訪問
2.服務器驗證用戶,通過校驗則向客戶端返回一個token
3.客戶端存儲token,并且在隨后的每一次請求中都帶著它
4.服務器校驗token并返回數據
每一次請求都需要token -Token應該放在請求header中 -我們還需要將服務器設置為接受來自所有域的請求,用Access-Control-Allow-Origin: *
二、實現步驟
1.配置過濾請求
在web-xml中配置需要認證的請求
<filter><filter-name>authFilter
</filter-name><filter-class>com.demo.filter.AuthFilter
</filter-class><init-param><param-name>ignore
</param-name><param-value>/**
</param-value></init-param><init-param><param-name>noIgnore
</param-name><param-value>/**/userApi/**/**
</param-value></init-param></filter>
2.實現過濾器
代碼如下(示例):
public class AuthFilter implements Filter {protected Pattern[] ignorePattern
= null;PathMatcher matcher
= new AntPathMatcher();String[] ignoreStrs
= null;String[] noIgnoreStrs
= null;public AuthFilter() {}@Overridepublic void destroy() {}@Overridepublic void doFilter(ServletRequest servletRequest
, ServletResponse servletResponse
, FilterChain chain
) throws IOException, ServletException {HttpServletRequest request
= (HttpServletRequest)servletRequest
;HttpServletResponse response
= (HttpServletResponse)servletResponse
;String uri
= request
.getRequestURI();if (this.checkIgnore(uri
) && !this.checkNoIgnore(uri
)) {chain
.doFilter(request
, response
);} else {Author.checkAuthorLocal(request
, response
, chain
);}}@Overridepublic void init(FilterConfig config
) throws ServletException {String ignore
= config
.getInitParameter("ignore");String noIgnore
= config
.getInitParameter("noIgnore");ignore
= StringUtils.defaultIfEmpty(ignore
, "");this.ignoreStrs
= ignore
.replaceAll("\\s", "").split(",");this.noIgnoreStrs
= noIgnore
.replaceAll("\\s", "").split(",");}public boolean checkIgnore(String requestUrl
) {boolean flag
= false;String[] var6
= this.ignoreStrs
;int var5
= this.ignoreStrs
.length
;for(int var4
= 0; var4
< var5
; ++var4
) {String pattern
= var6
[var4
];if (flag
= this.matcher
.match(pattern
, requestUrl
)) {break;}}return flag
;}public boolean checkNoIgnore(String requestUrl
) {boolean flag
= false;String[] var6
= this.noIgnoreStrs
;int var5
= this.noIgnoreStrs
.length
;for(int var4
= 0; var4
< var5
; ++var4
) {String pattern
= var6
[var4
];if (flag
= this.matcher
.match(pattern
, requestUrl
)) {break;}}return flag
;}
}
簡單認證的實現類
public class Author {public Author() {}public static void checkAuthorLocal(HttpServletRequest request
, HttpServletResponse response
, FilterChain chain
) throws IOException, ServletException {if (!request
.getMethod().equals("OPTIONS")) {String token
= request
.getHeader("oauth_token");if (!StringUtil.hasText(token
)) {token
= request
.getParameter("oauth_token");}String loginUserId
;if (StringUtil.hasText(token
)) {loginUserId
= getLoginUserId(token
);if (StringUtil.hasText(loginUserId
)) {setLoginUserId(token
, loginUserId
);chain
.doFilter(request
, response
);} else {response
.setStatus(HttpServletResponse.SC_METHOD_NOT_ALLOWED
);PrintWriter writer
= response
.getWriter();writer
.print("no access");return;}} else {response
.setStatus(HttpServletResponse.SC_METHOD_NOT_ALLOWED
);PrintWriter writer
= response
.getWriter();writer
.print("no access");return;}}}private static String getLoginUserId(String accessToken
) {String userId
= RedisClient.get(accessToken
);return userId
;}public static void setLoginUserId(String accessToken
, String userId
) {try {RedisClient.set(accessToken
, userId
, Cluster.getTimeoutSecond());} catch (Exception var3
) {var3
.printStackTrace();}}
}
if (!request
.getMethod().equals("OPTIONS")) {...}
這段代碼主要是解決后端接收不到前端傳入的header參數信息的問題,前面也提過。
用戶存儲的工具類
代碼如下(示例):
public class AuthSessionContext extends UserSessionContext {public static String USER_KEY
= "userKey";public static String CACHE_KEY_USER_IDENTITY
= "USER_IDENTITY_DATA";public static String CACHE_KEY_USER_IDENTITY_ID
= "USER_IDENTITY_ID";public static UserSessionContextService getContextService() {return (UserSessionContextService) BeanManager.getBean(UserSessionContextService.class);}@Deprecatedpublic static String getLoginPersonKey(HttpServletRequest request
) {return getLoginUserId(request
);}public static String getLoginIdentityId(HttpServletRequest request
) {String loginUserId
= getLoginUserId(request
);String loginIdentityId
= (String) RedisClient.get(CACHE_KEY_USER_IDENTITY_ID
+ loginUserId
);if (!StringUtil.hasText(loginIdentityId
)) {UserIdentityVO identity
= getIdentity();if (identity
!= null) {loginIdentityId
= identity
.getId();RedisClient.set(CACHE_KEY_USER_IDENTITY_ID
+ loginUserId
, loginIdentityId
, 60);}}return loginIdentityId
;}public static String getLoginIdentityId() {HttpServletRequest request
= WsbpWebContextListener.getRequest();return getLoginIdentityId(request
);}public static String getIdentityId() {UserIdentityVO identity
= getIdentity();return identity
!= null ? identity
.getId() : "";}public static void setLoginIdentityId(String loginUserId
, String loginIdentityId
) {RedisClient.set(CACHE_KEY_USER_IDENTITY_ID
+ loginUserId
, loginIdentityId
, Cluster.getTimeoutMillisecond());}public static String getLoginUserId(HttpServletRequest request
) {String token
= request
.getHeader("oauth_token");String userId
= null;if (token
!= null && !token
.isEmpty()) {userId
= (String)RedisClient.get(token
);}return userId
;}public static String getLoginUserId() {HttpServletRequest request
= WsbpWebContextListener.getRequest();return getLoginUserId(request
);}public static String getLoginUserName() {UserVO loginUser
= getLoginUser();return loginUser
!= null ? loginUser
.getUserName() : "";}public static UserVO getLoginUser() {return getContextService().getUserByUserId(getLoginUserId());}public static String getLoginDepartment(HttpServletRequest request
) {String identityId
= getLoginIdentityId(request
);return getContextService().getLoginDepartment(identityId
);}public static String getDeptId() {HttpServletRequest request
= WsbpWebContextListener.getRequest();String identityId
= getLoginIdentityId(request
);return getContextService().getLoginDepartment(identityId
);}public static DepartmentVO getDept() {return getContextService().getDepartment(getDeptId());}public static String getDeptName() {DepartmentVO department
= getDept();return department
!= null ? department
.getName() : "";}public static String getLoginOrganization(HttpServletRequest request
) {String identityId
= getLoginIdentityId(request
);return getContextService().getLoginOrganization(identityId
);}public static String getOrgId() {HttpServletRequest request
= WsbpWebContextListener.getRequest();String identityId
= getLoginIdentityId(request
);return getContextService().getLoginOrganization(identityId
);}public static OrganizationVO getOrg() {DepartmentVO dept
= getDept();return dept
!= null ? dept
.getOrg() : null;}public static String getOrgName() {OrganizationVO org
= getOrg();return org
!= null ? org
.getName() : "";}public static boolean isInAnyRole(HttpServletRequest request
, String roles
) {String identityId
= getLoginIdentityId(request
);return getContextService().checkIsInAnyRole(identityId
, roles
);}public static boolean isInRole(HttpServletRequest request
, String roles
) {String identityId
= getLoginIdentityId(request
);return getContextService().checkIsInRole(identityId
, roles
);}public static List<RoleVO> getRoleListInRoles(HttpServletRequest request
, String roles
) {String identityId
= getLoginIdentityId(request
);return getContextService().getRoleListInRoles(identityId
, roles
);}public static boolean isInAnyCase(HttpServletRequest request
, String cases
) {String identityId
= getLoginIdentityId(request
);return getContextService().checkIsInAnyCase(identityId
, cases
);}public static boolean isInCase(HttpServletRequest request
, String cases
) {String identityId
= getLoginIdentityId(request
);boolean checkIsInCase
= getContextService().checkIsInCase(identityId
, cases
);return checkIsInCase
;}public static List<RoleVO> getmyUserRoleList(HttpServletRequest request
) {String identityId
= getLoginIdentityId(request
);return getContextService().getmyUserRoleList(identityId
);}public static RoleVO getmyUserhighestRole(HttpServletRequest request
) {String identityId
= getLoginIdentityId(request
);return getContextService().getmyUserhighestRole(identityId
);}public static String getmyTenementIdByUserId(HttpServletRequest request
) {String userId
= getLoginUserId(request
);return getContextService().getLoginTenementId(userId
);}public static void setLoginUser(HttpServletResponse response
, TsysUserVO user
, String userKey
) {try {String userId
= user
.getId();addCookie(response
, USER_KEY
, userKey
, "/", getSessionTimeout());addCookie(response
, Cluster.SESSION_KEY
, userKey
, "/", getSessionTimeout());RedisClient.set(userKey
, userId
, Cluster.getTimeoutSecond());RedisClient.set(userKey
+"Username", user
.getUserName(), Cluster.getTimeoutSecond());RedisClient.set(user
.getUserName(), user
.getPasswd(), Cluster.getTimeoutSecond());} catch (Exception e
) {e
.printStackTrace();}}private static void addCookie(HttpServletResponse response
, String name
, String value
, String path
, int maxAge
) {Cookie cookie
= new Cookie(name
, value
);cookie
.setPath(path
);cookie
.setMaxAge(maxAge
);response
.addCookie(cookie
);}
3.登錄接口
登錄邏輯判斷用戶名密碼,通過則將用戶信息返回,同時將用戶信息存在Redis中,向前端返回token
代碼如下(示例):
@RequestMapping(value
= "/login", method
= RequestMethod.POST
, produces
= "application/json;charset=utf-8")@ResponseBodypublic String login(@RequestBody String jsonStr
, HttpServletResponse response
) {JSONObject object
= JSON
.parseObject(jsonStr
);String account
= object
.getString("account");String password
= object
.getString("password");JSONObject result
= new JSONObject(3);if (StringUtils.isEmpty(account
) || StringUtils.isEmpty(password
)) {result
.put("state", false);result
.put("msg", "賬號或密碼不能為空");return result
.toString();}User userInfo
= userService
.login(account
, password
);if (userInfo
instanceof String) {return (String) userInfo
;} else {User user
= (User) userInfo
;String id
= user
.getId();String s
= id
+ System.currentTimeMillis();String token
= MD5Util.MD5(s
);Author.setLoginUserId(token
, user
.getId());AuthSessionContext.setLoginUser(response
, user
, token
);result
.put("state", true);result
.put("oauth_token", token
);}return result
.toString();}
4.登錄之后獲取用戶信息
通過擴展工具類獲取信息。
代碼如下(示例):
String userId
= AuthSessionContext.getLoginUserId();
User userInfo
= AuthSessionContext.getLoginUser();
總結
基于token最直觀的好處就是無狀態和可擴展性,token可以設置過期時間,超過時間之后,用戶將重新登錄。還可以根據相同的授權許可使特定的token甚至一組token無效來實現用戶退出登錄。
總結
以上是生活随笔為你收集整理的基于token身份认证的完整实例的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。