效果圖:
原理:此處為img src每次點擊從后台獲取流文件,存到session中,下次驗證session即可。
前台
<img style="height:22px;" id="codeImg" alt="點擊更換" title="點擊更換" src="" />
js
$(document).ready(function() { changeCode(); $("#codeImg").bind("click", changeCode); });function genTimestamp() { var time = new Date(); return time.getTime(); } function changeCode() { $("#codeImg").attr("src", "code.do?t=" + genTimestamp()); }
后台controller:
package com.fh.controller.system.secCode; import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; import java.awt.font.FontRenderContext; import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.Random; import javax.imageio.ImageIO; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletResponse; import org.apache.shiro.SecurityUtils; import org.apache.shiro.session.Session; import org.apache.shiro.subject.Subject; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import com.fh.util.Const; /** * 類名稱:登錄驗證碼 * 類描述: * 作者單位: * 聯系方式: * @version */ @Controller @RequestMapping("/code") public class SecCodeController { @RequestMapping public void generate(HttpServletResponse response){ ByteArrayOutputStream output = new ByteArrayOutputStream(); String code = drawImg(output); Subject currentUser = SecurityUtils.getSubject(); Session session = currentUser.getSession(); session.setAttribute(Const.SESSION_SECURITY_CODE, code); try { ServletOutputStream out = response.getOutputStream(); output.writeTo(out); } catch (IOException e) { e.printStackTrace(); } } private String drawImg(ByteArrayOutputStream output){ String code = ""; for(int i=0; i<4; i++){ code += randomChar(); } int width = 70; int height = 25; BufferedImage bi = new BufferedImage(width,height,BufferedImage.TYPE_3BYTE_BGR); Font font = new Font("Times New Roman",Font.PLAIN,20); Graphics2D g = bi.createGraphics(); g.setFont(font); Color color = new Color(66,2,82); g.setColor(color); g.setBackground(new Color(226,226,240)); g.clearRect(0, 0, width, height); FontRenderContext context = g.getFontRenderContext(); Rectangle2D bounds = font.getStringBounds(code, context); double x = (width - bounds.getWidth()) / 2; double y = (height - bounds.getHeight()) / 2; double ascent = bounds.getY(); double baseY = y - ascent; g.drawString(code, (int)x, (int)baseY); g.dispose(); try { ImageIO.write(bi, "jpg", output); } catch (IOException e) { e.printStackTrace(); } return code; } private char randomChar(){ Random r = new Random(); String s = "ABCDEFGHJKLMNPRSTUVWXYZ0123456789"; return s.charAt(r.nextInt(s.length())); } }
附加登錄驗證session:
@RequestMapping(value="/login_login" ,produces="application/json;charset=UTF-8") @ResponseBody public Object login()throws Exception{ Map<String,String> map = new HashMap<String,String>(); PageData pd = new PageData(); pd = this.getPageData(); String errInfo = ""; String KEYDATA[] = pd.getString("KEYDATA").replaceAll("qq313596790fh", "").replaceAll("QQ978336446fh", "").split(",fh,"); if(null != KEYDATA && KEYDATA.length == 3){ Session session = Jurisdiction.getSession(); String sessionCode = (String)session.getAttribute(Const.SESSION_SECURITY_CODE); //獲取session中的驗證碼 String code = KEYDATA[2]; if(null == code || "".equals(code)){//判斷效驗碼 errInfo = "nullcode"; //效驗碼為空 }else{ String USERNAME = KEYDATA[0]; //登錄過來的用戶名 String PASSWORD = KEYDATA[1]; //登錄過來的密碼 pd.put("USERNAME", USERNAME); if(Tools.notEmpty(sessionCode) && sessionCode.equalsIgnoreCase(code)){ //判斷登錄驗證碼 String passwd = new SimpleHash("SHA-1", USERNAME, PASSWORD).toString(); //密碼加密 pd.put("PASSWORD", passwd); pd = userService.getUserByNameAndPwd(pd); //根據用戶名和密碼去讀取用戶信息 if(pd != null){ pd.put("LAST_LOGIN",DateUtil.getTime().toString()); userService.updateLastLogin(pd); User user = new User(); user.setUSER_ID(pd.getString("USER_ID")); user.setUSERNAME(pd.getString("USERNAME")); user.setPASSWORD(pd.getString("PASSWORD")); user.setNAME(pd.getString("NAME")); user.setRIGHTS(pd.getString("RIGHTS")); user.setROLE_ID(pd.getString("ROLE_ID")); user.setLAST_LOGIN(pd.getString("LAST_LOGIN")); user.setIP(pd.getString("IP")); user.setSTATUS(pd.getString("STATUS")); session.setAttribute(Const.SESSION_USER, user); //把用戶信息放session中 session.removeAttribute(Const.SESSION_SECURITY_CODE); //清除登錄驗證碼的session //shiro加入身份驗證 Subject subject = SecurityUtils.getSubject(); UsernamePasswordToken token = new UsernamePasswordToken(USERNAME, PASSWORD); try { subject.login(token); } catch (AuthenticationException e) { errInfo = "身份驗證失敗!"; } }else{ errInfo = "usererror"; //用戶名或密碼有誤 logBefore(logger, USERNAME+"登錄系統密碼或用戶名錯誤"); } }else{ errInfo = "codeerror"; //驗證碼輸入有誤 } if(Tools.isEmpty(errInfo)){ errInfo = "success"; //驗證成功 logBefore(logger, USERNAME+"登錄系統"); } } }else{ errInfo = "error"; //缺少參數 } map.put("result", errInfo); return AppUtil.returnObject(new PageData(), map); }