為了方便用戶登錄找田,幾乎所有的網(wǎng)站都實現(xiàn)了“記住密碼”、“自動登陸”這樣似乎人性化的功能着憨。
我也很喜歡這個功能墩衙,因為我自己的腦子實在是討厭記東西。
為了安全起見甲抖,我的密碼都設(shè)置的很復(fù)雜漆改,滿足“數(shù)字+特殊符號+英文字母大小寫”。
但密碼一復(fù)雜准谚,我就總記不住挫剑,就想讓網(wǎng)站替我記住。
但殊不知柱衔,這背后隱藏著巨大的風險樊破。
我先勸大家一聲:“危險愉棱,不要隨意讓網(wǎng)站記住密碼自動登陸!”
要了解事情的真相哲戚,請隨我來看一看如何利用cookie實現(xiàn)記住密碼自動登陸奔滑。
第一步、構(gòu)建form表單
<form class="form-signin required-validate" action="${ctx}/login?callbackType=forward">
${token}
<div class="form-group">
<div class="row">
<input class="form-control" type="text" autofocus name="username" value="${username}" placeholder="請輸入會員編號" />
</div>
</div>
<div class="blank10"></div>
<div class="form-group">
<div class="row">
<input class="form-control" type="password" name="password" value="${password}" placeholder="請輸入登陸密碼" />
</div>
</div>
<div class="form-group">
<div class="row">
<div class="checkbox">
<label> <input type="checkbox" value="1" <c:if test="${isSave == 'true'}">checked</c:if> name="isSave" /> 下次自動登錄
</label>
</div>
</div>
</div>
<div class="form-group">
<div class="row">
<button class="btn btn-lg btn-primary btn-block" type="submit">登錄</button>
</div>
</div>
</form>
第二步顺少、登陸時利用cookie記住密碼
@RequestMapping("/login")
public ModelAndView login(HttpServletResponse response,
@RequestParam(value = "username", required = false) String username,
@RequestParam(value = "password", required = false) String password) {
try {
boolean isSave = getParaToBoolean("isSave", false);
logger.debug("isSaved " + isSave);
// 嘗試獲取cookie
String cookieUser = CookieUtil.getCookieByName(request, Constants.COOKIE_USER);
logger.debug("cookie的值為:" + cookieUser);
// 驗證用戶信息
Members user = memberService.selectByUsername(username);
// 如果IP不同朋其,則清除cookie
if (cookieUser != null) {
if (!user.getLastip().equals(request.getRemoteAddr())) {
// 移除自動登錄cookie信息
CookieUtil.removeCookie(response, Constants.COOKIE_USER);// 刪除cookie
}
}
MembersValidator.checkPassword(password, user.getPassword());
user.setLastip(request.getRemoteAddr());// 更新登錄id 和最后登錄時間
memberService.updateLastvisit(user);
checkToken();
int max_age = Variables.cookie_expire * 3600 * 24;
if (isSave) {
// 將自動登錄信息存入cookie
CookieUtil.setCookie(response, Constants.COOKIE_USER,
DesUtils.encrypt(username + "," + password + "," + isSave), max_age);
} else {
// 移除自動登錄cookie信息
CookieUtil.removeCookie(response, Constants.COOKIE_USER);// 刪除cookie
}
logger.debug("登陸成功后跳轉(zhuǎn)");
return ajaxDoneSuccess(user.getUid().toString(), (String) getSessionAttr(Constants.BEFORE_LOGIN_URL));
} catch (Exception e) {
logger.error(e.getMessage());
logger.error(e.getMessage(), e);
return ajaxDoneError(Constants.SERVER_ERROR);
}
}
這部分代碼也很清晰明了,就不做多的解釋脆炎。
附上CookieUtil.java類
/**
* Cookie工具類
*
*/
public class CookieUtil {
/**
* 添加cookie
*
* @param response
* @param name
* @param value
* @param maxAge
*/
public static void setCookie(HttpServletResponse response, String name, String value, int maxAge) {
Cookie cookie = new Cookie(name, value);
cookie.setPath("/");
if (maxAge > 0) {
cookie.setMaxAge(maxAge);
}
response.addCookie(cookie);
}
/**
* 刪除cookie
*
* @param response
* @param name
*/
public static void removeCookie(HttpServletResponse response, String name) {
Cookie uid = new Cookie(name, null);
uid.setPath("/");
uid.setMaxAge(0);
response.addCookie(uid);
}
/**
* 獲取cookie值
*
* @param request
* @return
*/
public static String getCookieByName(HttpServletRequest request, String cookieName) {
Cookie cookies[] = request.getCookies();
if (cookies == null) {
return null;
}
for (Cookie cookie : cookies) {
if (cookie.getName().equals(cookieName)) {
return cookie.getValue();
}
}
return null;
}
}
第三步梅猿、從cookie中取出登陸用戶名、密碼等關(guān)鍵信息
@RequestMapping("/initLogin")
public ModelAndView initLogin() {
logger.debug("進入登陸頁");
try {
ModelAndView initView = new ModelAndView("login");
String cookieUser = CookieUtil.getCookieByName(request, Constants.COOKIE_USER);
if (cookieUser != null) {
String decode = DesUtils.decrypt(cookieUser);
String[] cookieUsers = decode.split(",");
initView.addObject("username", cookieUsers[0]);
initView.addObject("password", cookieUsers[1]);
initView.addObject("isSave", cookieUsers[2]);
}
createToken();
return initView;
} catch (Exception e) {
logger.error(e.getMessage());
logger.error(e.getMessage(), e);
return error300(Constants.SERVER_ERROR);
}
}
當我輸入了賬號秒裕、以及密碼后袱蚓,勾選上“下次自動登陸”,那么系統(tǒng)在驗證通過后簇爆,就會通過cookie記住我的用戶名和密碼癞松,下次不用再輸入賬號和密碼,直接點擊登陸就進入系統(tǒng)入蛆。
到此為止响蓉,自動登陸的功能已經(jīng)實現(xiàn)了。
那么哨毁,現(xiàn)在可以說一些負責任的話了枫甲。
在瀏覽器的開發(fā)者模式下,注意紅色框中的“type='password'”扼褪,此時我們將type修改為text想幻。
注意,注意话浇,你是不是已經(jīng)發(fā)現(xiàn)了脏毯,密碼不再是密碼了,成了明文了幔崖。
你食店,此刻是否心驚肉跳了?
對赏寇,XX(這文章會被和諧嗎吉嫩,不至于吧,這早已經(jīng)不是秘密了嗅定,是個程序員都知道)也這樣自娩!
所以,作為一個不務(wù)正業(yè)的IT狗來說渠退,我奉勸各位忙迁,“危險脐彩,不要隨意讓網(wǎng)站記住密碼自動登陸!”
假如你的電腦這會被我用动漾,而你又選擇讓網(wǎng)站記住密碼丁屎,那對不起了荠锭,你再復(fù)雜的密碼也不過是一串明文而已旱眯!
當然了,放心了证九,我是不會去看你的密碼了删豺。
不過瀏覽器會不會看你的密碼我就不敢保證了。
既然為了安全愧怜,設(shè)置了超長超復(fù)雜的密碼呀页,那么每次就手動輸一下嘛,不麻煩拥坛,安全得很蓬蝶!