日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術(shù)文章
文章詳情頁

java token生成和校驗的實例代碼

瀏覽:22日期:2022-08-24 16:10:27

現(xiàn)在越來越多的登錄方式都用到了token作為用戶登錄令牌,所以實現(xiàn)了一個token生成和校驗案例。

缺點:該實現(xiàn)方式token是存儲在內(nèi)存中,不適合分布式項目,如需改為分布式項目部署,可把token存儲在redis中,其中的實現(xiàn)原理還是保持不變。

一)token編碼工具類

package com.oysept.token.utils; /** * token編碼工具類 * @author ouyangjun */public class TokenEncryptUtils { // 編碼密碼,可自定義 private static final String ENCODED_PASSWORD = 'ouyangjun'; /** * 編碼 * @param str * @return */ public static String encoded(String str) { return strToHex(encodedString(str, ENCODED_PASSWORD)); } /** * 轉(zhuǎn)換 * @param str * @param password * @return */ private static String encodedString(String str, String password) { char[] pwd = password.toCharArray(); int pwdLen = pwd.length; char[] strArray = str.toCharArray(); for (int i=0; i<strArray.length; i++) { strArray[i] = (char)(strArray[i] ^ pwd[i%pwdLen] ^ pwdLen); } return new String(strArray); } private static String strToHex(String s) { return bytesToHexStr(s.getBytes()); } private static String bytesToHexStr(byte[] bytesArray) { StringBuilder builder = new StringBuilder(); String hexStr; for (byte bt : bytesArray) { hexStr = Integer.toHexString(bt & 0xFF); if (hexStr.length() == 1) { builder.append('0'); builder.append(hexStr); }else{ builder.append(hexStr); } } return builder.toString(); } /** * 解碼 * @param str * @return */ public static String decoded(String str) { String hexStr = null; try { hexStr = hexStrToStr(str); } catch (Exception e) { e.printStackTrace(); } if (hexStr != null) { hexStr = encodedString(hexStr, ENCODED_PASSWORD); } return hexStr; } private static String hexStrToStr(String hexStr) { return new String(hexStrToBytes(hexStr)); } private static byte[] hexStrToBytes(String hexStr) { String hex; int val; byte[] btHexStr = new byte[hexStr.length()/2]; for (int i=0; i<btHexStr.length; i++) { hex = hexStr.substring(2*i, 2*i+2); val = Integer.valueOf(hex, 16); btHexStr[i] = (byte) val; } return btHexStr; } }

二)token生成和校驗工具類(包含main方法測試)

package com.oysept.token.utils; import java.util.HashMap;import java.util.Map;import java.util.Map.Entry; /** * token生成和校驗 * @author ouyangjun */public class TokenUtils { private static Map<String,String> MAP_TOKENS = new HashMap<String,String>(); private static final int VALID_TIME = 60*60*2; // token有效期(秒) public static final String TOKEN_ERROR = 'F'; // 非法 public static final String TOKEN_OVERDUE = 'G'; // 過期 public static final String TOKEN_FAILURE = 'S'; // 失效 /** * 生成token,該token長度不一致,如需一致,可自行MD5或者其它方式加密一下 * 該方式的token只存在磁盤上,如果項目是分布式,最好用redis存儲 * @param str: 該字符串可自定義,在校驗token時要保持一致 * @return */ public static String getToken(String str) { String token = TokenEncryptUtils.encoded(getCurrentTime()+','+str); MAP_TOKENS.put(str, token); return token; } /** * 校驗token的有效性 * @param token * @return */ public static String checkToken(String token) { if (token == null) { return TOKEN_ERROR; } try{ String[] tArr = TokenEncryptUtils.decoded(token).split(','); if (tArr.length != 2) { return TOKEN_ERROR; } // token生成時間戳 int tokenTime = Integer.parseInt(tArr[0]); // 當(dāng)前時間戳 int currentTime = getCurrentTime(); if (currentTime-tokenTime < VALID_TIME) { String tokenStr = tArr[1]; String mToken = MAP_TOKENS.get(tokenStr); if (mToken == null) { return TOKEN_OVERDUE; } else if(!mToken.equals(token)) { return TOKEN_FAILURE; } return tokenStr; } else { return TOKEN_OVERDUE; } }catch (Exception e) { e.printStackTrace(); } return TOKEN_ERROR; } /**獲取當(dāng)前時間戳(10位整數(shù))*/ public static int getCurrentTime() { return (int)(System.currentTimeMillis()/1000); } /** * 移除過期的token */ public static void removeInvalidToken() { int currentTime = getCurrentTime(); for (Entry<String,String> entry : MAP_TOKENS.entrySet()) { String[] tArr = TokenEncryptUtils.decoded(entry.getValue()).split(','); int tokenTime = Integer.parseInt(tArr[0]); if(currentTime-tokenTime > VALID_TIME){ MAP_TOKENS.remove(entry.getKey()); } } } /** * 測試 * @param args */ public static void main(String[] args) { String str = 'username_and_password'; // 獲取token String token = TokenUtils.getToken(str); System.out.println('token Result: ' + token); // 校驗token String checkToken = TokenUtils.checkToken(token); System.out.println('checkToken Result: ' + checkToken); if(str.equals(checkToken)) { System.out.println('==>token verification succeeded!'); } }}

補(bǔ)充知識:JAVA后端生成Token(令牌),用于校驗客戶端,防止重復(fù)提交

1.概述:在web項目中,服務(wù)端和前端經(jīng)常需要交互數(shù)據(jù),有的時候由于網(wǎng)絡(luò)相應(yīng)慢,客戶端在提交某些敏感數(shù)據(jù)(比如按照正常的業(yè)務(wù)邏輯,此份數(shù)據(jù)只能保存一份)時,如果前端多次點擊提交按鈕會導(dǎo)致提交多份數(shù)據(jù),這種情況我們是要防止發(fā)生的。

2.解決方法:

①前端處理:在提交之后通過js立即將按鈕隱藏或者置為不可用。

②后端處理:對于每次提交到后臺的數(shù)據(jù)必須校驗,也就是通過前端攜帶的令牌(一串唯一字符串)與后端校驗來判斷當(dāng)前數(shù)據(jù)是否有效。

3.總結(jié):第一種方法相對來說比較簡單,但是安全系數(shù)不高,第二種方法從根本上解決了問題,所以我推薦第二種方法。

4.核心代碼:

生成Token的工具類:

/** * 生成Token的工具類: */package red.hearing.eval.modules.token; import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;import java.util.Random; import sun.misc.BASE64Encoder; /** * 生成Token的工具類 * @author zhous * @since 2018-2-23 13:59:27 * */public class TokenProccessor { private TokenProccessor(){}; private static final TokenProccessor instance = new TokenProccessor(); public static TokenProccessor getInstance() { return instance; } /** * 生成Token * @return */ public String makeToken() { String token = (System.currentTimeMillis() + new Random().nextInt(999999999)) + ''; try { MessageDigest md = MessageDigest.getInstance('md5'); byte md5[] = md.digest(token.getBytes()); BASE64Encoder encoder = new BASE64Encoder(); return encoder.encode(md5); } catch (NoSuchAlgorithmException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; }}

Token通用工具類:

/** * */package red.hearing.eval.modules.token; import javax.servlet.http.HttpServletRequest; import org.apache.commons.lang3.StringUtils; /** * Token的工具類 * @author zhous * @since 2018-2-23 14:01:41 * */public class TokenTools { /** * 生成token放入session * @param request * @param tokenServerkey */ public static void createToken(HttpServletRequest request,String tokenServerkey){ String token = TokenProccessor.getInstance().makeToken(); request.getSession().setAttribute(tokenServerkey, token); } /** * 移除token * @param request * @param tokenServerkey */ public static void removeToken(HttpServletRequest request,String tokenServerkey){ request.getSession().removeAttribute(tokenServerkey); } /** * 判斷請求參數(shù)中的token是否和session中一致 * @param request * @param tokenClientkey * @param tokenServerkey * @return */ public static boolean judgeTokenIsEqual(HttpServletRequest request,String tokenClientkey,String tokenServerkey){ String token_client = request.getParameter(tokenClientkey); if(StringUtils.isEmpty(token_client)){ return false; } String token_server = (String) request.getSession().getAttribute(tokenServerkey); if(StringUtils.isEmpty(token_server)){ return false; } if(!token_server.equals(token_client)){ return false; } return true; } }

使用方法:

①在輸出前端頁面的時候調(diào)用TokenTools.createToken方法,會把本次生成的token放入session中。

②然后在前端頁面提交數(shù)據(jù)時從session中獲取token,然后添加到要提交的數(shù)據(jù)中。

③服務(wù)端接受數(shù)據(jù)后調(diào)用judgeTokenIsEqual方法判斷兩個token是否一致,如果不一致則返回,不進(jìn)行處理。

備注:tokenClientkey和tokenServerkey自定義,調(diào)用judgeTokenIsEqual方法時的tokenClientkey一定要與前端頁面的key一致。

以上這篇java token生成和校驗的實例代碼就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持好吧啦網(wǎng)。

標(biāo)簽: Java
相關(guān)文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
日韩欧美一区二区三区免费观看| 欧美手机在线| 免费日韩av片| 久热re这里精品视频在线6| 影音先锋久久精品| 日韩一区精品| 麻豆成人在线观看| 精品三区视频| 欧美成人精品三级网站| 999精品一区| 视频一区在线播放| 综合激情网站| 欧美国产精品| 视频二区不卡| 久久午夜视频| 国产精品xxx在线观看| 亚洲午夜天堂| 视频一区中文字幕| 免费视频一区二区三区在线观看| 丝袜诱惑一区二区| 亚洲一区二区成人| 久久国产乱子精品免费女| 精品视频国产| 国产精品毛片| 久久国产精品美女| 欧美va天堂在线| 日韩一区精品字幕| 九九99久久精品在免费线bt| 午夜电影亚洲| 国产精品videossex久久发布| 久久精品免费一区二区三区| 日韩**一区毛片| 在线中文字幕播放| 在线观看视频免费一区二区三区| 精品国产一区二| 国产精品毛片在线| 国模精品一区| 亚洲精品看片| jizzjizz中国精品麻豆| 蜜桃伊人久久| 欧美日韩国产v| 蜜桃免费网站一区二区三区| 高清精品久久| 日韩二区在线观看| 一区二区三区视频免费观看| 欧美在线观看天堂一区二区三区| 蜜桃国内精品久久久久软件9| 国产精品久久| 欧美专区在线| 蜜臀久久精品| 久久精品xxxxx| 先锋影音久久久| 婷婷综合六月| 国产极品一区| 伊人精品久久| 久久国产成人午夜av影院宅| 国产精品一区二区免费福利视频| 国产亚洲精品久久久久婷婷瑜伽| 成人日韩av| 国产精品网址| 亚洲久草在线| 99xxxx成人网| 亚洲91精品| 韩国一区二区三区视频| 日本亚洲最大的色成网站www| 一区免费视频| 神马午夜在线视频| 精品国产乱码| 欧美日韩一区自拍| 午夜亚洲精品| 欧美日韩国产综合网| 精品久久久网| 国产精品亚洲片在线播放| 亚洲精品婷婷| 亚洲深夜福利| 欧美日韩国产综合网| 99精品视频在线| 日韩在线看片| 日韩成人精品一区| 国产精品国产三级在线观看| 日韩精品a在线观看91| 免费在线观看精品| 香蕉视频成人在线观看| 亚洲精品成人| 欧美日韩视频一区二区三区| 欧洲精品一区二区三区| 欧美激情日韩| 国产激情综合| 久久亚州av| 国产成人精品一区二区三区视频| 欧美黑人巨大videos精品| 国产精品一区二区中文字幕| 国产欧美一区| 国产精品久久久久77777丨| 国产精品欧美大片| 国产精品亚洲综合色区韩国| 国产日韩欧美| 免费一级欧美片在线观看网站| 国产精品videossex久久发布| 久久国产精品色av免费看| 国产精品第十页| 国产精品www994| 精品亚洲二区| 日韩和的一区二在线| 91精品国产乱码久久久久久久| 999国产精品永久免费视频app| 999久久久免费精品国产| 一本一道久久a久久精品蜜桃| 午夜一区在线| 青青草伊人久久| 国产精品sss在线观看av| 精品亚洲免a| 久久在线免费| 免费看日韩精品| 欧美精品国产一区| 精品三级在线观看视频| 精品72久久久久中文字幕| 欧美激情另类| 狠狠干成人综合网| 亚洲3区在线| 鲁大师精品99久久久| 日韩精品中文字幕第1页| 国产亚洲精品v| 日韩成人午夜精品| 国产一区一一区高清不卡| 99精品国产一区二区三区| 丝袜诱惑制服诱惑色一区在线观看 | 国产va在线视频| 亚洲成a人片| 另类激情亚洲| 国产精品久久久久久久免费软件| 日韩久久视频| 蜜臀av一区二区三区| 国产日产精品_国产精品毛片| 国产第一亚洲| 野花国产精品入口| 国产精品国码视频| 99精品国产一区二区三区| 香蕉久久国产| 国产精品啊v在线| 久久视频精品| 欧美片第1页综合| 韩国三级一区| 日韩一区二区三区四区五区| sm久久捆绑调教精品一区| 国产农村妇女精品一二区| 国产精品久久免费视频| 亚洲调教视频在线观看| 欧美日韩精品一区二区三区视频| 日韩免费久久| 日本h片久久| 亚洲欧美一区在线| 国产精品亚洲片在线播放| 精品欧美激情在线观看| 悠悠资源网久久精品| 风间由美中文字幕在线看视频国产欧美| 国产亚洲久久| 日本成人在线网站| 美女网站视频一区| 日韩成人av影视| 欧洲毛片在线视频免费观看| 欧美日韩1区| 一区在线观看| 国产精品xxx| 亚洲久草在线| 欧美日韩国产在线观看网站| 麻豆精品久久久| 色狠狠一区二区三区| 99久久亚洲精品蜜臀| 卡一卡二国产精品| 日韩中文av| 五月天久久777| 久久av国产紧身裤| 最近国产精品视频| 老牛影视精品| 国产麻豆一区二区三区| aa国产精品| 尤物tv在线精品| 国产精品精品| 久久av电影| 日韩精品第一| 日韩在线一区二区| 女主播福利一区| 99久久99久久精品国产片果冰| 精品成人18| 国产福利资源一区| 久久精品 人人爱| 石原莉奈在线亚洲三区| 91精品国产自产在线观看永久∴| 伊人久久视频| 精品久久国产一区| 国产精品久久久久久久久久妞妞| 日韩精品社区| 亚洲婷婷丁香| 麻豆久久精品| 美女黄网久久| 国产精品婷婷| 99re国产精品| 9色精品在线| 国产一级一区二区|