Recently, the technology of login verification through the code parameter of the verification code picture was used in the project. Here is a record for reference
design sketch
Backend interface writing
Verification code tool class
First define a tool class for generating verification code pictures
import javax.imageio.ImageIO; import java.awt.*; import java.awt.image.BufferedImage; import java.io.IOException; import java.io.OutputStream; import java.util.Random; /** * @author Anan * code Build tool class */ public class CodeUtils { /** * Width of generated verification code picture */ private int width = 100; /** * Height of generated verification code picture */ private int height = 30; /** * character style */ private String[] fontNames = { "Song typeface", "Regular script", "official script", "Microsoft YaHei " }; /** * Define the background color of the verification code picture as white */ private Color bgColor = new Color(255, 255, 255); /** * Generate random */ private Random random = new Random(); /** * Define code characters */ private String codes = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; /** * Record random string */ private String text; /** * Get a random color * @return */ private Color randomColor() { int red = random.nextInt(150); int green = random.nextInt(150); int blue = random.nextInt(150); return new Color(red, green, blue); } /** * Get a random font * * @return */ private Font randomFont() { String name = fontNames[random.nextInt(fontNames.length)]; int style = random.nextInt(4); int size = random.nextInt(5) + 24; return new Font(name, style, size); } /** * Get a random character * * @return */ private char randomChar() { return codes.charAt(random.nextInt(codes.length())); } /** * Create a blank BufferedImage object * * @return */ private BufferedImage createImage() { BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics2D g2 = (Graphics2D) image.getGraphics(); //Set the background color of the verification code picture g2.setColor(bgColor); g2.fillRect(0, 0, width, height); return image; } public BufferedImage getImage() { BufferedImage image = createImage(); Graphics2D g2 = (Graphics2D) image.getGraphics(); StringBuffer sb = new StringBuffer(); for (int i = 0; i < 4; i++) { String s = randomChar() + ""; sb.append(s); g2.setColor(randomColor()); g2.setFont(randomFont()); float x = i * width * 1.0f / 4; g2.drawString(s, x, height - 8); } this.text = sb.toString(); drawLine(image); return image; } /** * Draw interference line * * @param image */ private void drawLine(BufferedImage image) { Graphics2D g2 = (Graphics2D) image.getGraphics(); int num = 5; for (int i = 0; i < num; i++) { int x1 = random.nextInt(width); int y1 = random.nextInt(height); int x2 = random.nextInt(width); int y2 = random.nextInt(height); g2.setColor(randomColor()); g2.setStroke(new BasicStroke(1.5f)); g2.drawLine(x1, y1, x2, y2); } } public String getText() { return text; } public static void output(BufferedImage image, OutputStream out) throws IOException { ImageIO.write(image, "JPEG", out); } }
Controller definition request
Call at the front end to generate a picture of the verification code, and store the code of the verification code in the session for verification during login judgment
/** * Generate verification code picture * @param request * @param res * @throws IOException */ @GetMapping("/code") public void code(HttpServletRequest request, HttpServletResponse res) throws IOException { CodeUtils code = new CodeUtils(); BufferedImage image = code.getImage(); String text = code.getText(); HttpSession session = request.getSession(true); session.setAttribute("code", text); CodeUtils.output(image,res.getOutputStream()); }
validate logon
The login interface also uses token here. You can directly see the comments by using code verification only
//Judge whether the code is correct. For the subsequent code, use if to judge the output when the code is wrong. When there is no code in the session or the code parameters passed from the front end are inconsistent with the code parameters in the back-end session, you can judge that the verification code is wrong
Note: ① 𞓜 behind! Indicates a non - uppercase() used to be case insensitive
/** * Log in to implement the token and verify the code * @param param * @param request * @return */ @PostMapping(value = "/login") public Object login(@RequestBody Map<String,String> param, HttpServletRequest request, HttpServletResponse response){ JSONObject jsonObject = new JSONObject(); String root_name = param.get("root_name"); String root_password = param.get("root_password"); Root root = rootService.checkRoot(root_name,root_password); //Determine whether the code is correct if(request.getSession(true) .getAttribute("code")==null || !param.get("code").toUpperCase() .equals(request.getSession(true) .getAttribute("code") .toString().toUpperCase())){ jsonObject.put("message", "code error!"); return jsonObject; } //Login judgment else if (root == null){ jsonObject.put("message", "login error!"); }else { //Login succeeded. Use session to store account and password HttpSession session =request.getSession(true); session.setAttribute("root",root); String token = rootService.getToken(root); jsonObject.put("message", "login success!"); jsonObject.put("token", token); jsonObject.put("root_img", root.getRoot_img()); Cookie cookie = new Cookie("token", token); cookie.setPath("/"); response.addCookie(cookie); } return jsonObject; }
front end
to configure
Note that because the front and back ends are developed separately, each ajax request from the front end is new, and the sessionID of each request is different, so the session used each time is not the same, so that the value in the session is null when logging in.
It needs to be in main. Of vue project Configure axios.js defaults. Withcredentials is true, so that the browser's cookie is brought with each request, so that the session used by the back end is the same.
axios.defaults.withCredentials = true;
Picture request and click refresh
Define the verification code picture in the login box
<el-form-item prop="code"> <span><i class="iconfont icon-icon_anquan" style="font-size: 25px"></i></span> <el-input type="text" auto-complete="false" v-model="loginForm.code" placeholder="Click the picture to replace the verification code" style="width: 60%;margin-left: 10px" @keyup.enter.native="submitLogin('loginForm')"></el-input> <el-image class="codeImg" :src="imgUrl" @click="resetImg"></el-image> </el-form-item>
Here you define a verification code image style
.codeImg { margin-top: 5px; float: right; }
Define the corresponding imgUrl in the data parameter, and new Date() generates a random event to replace the verification code
imgUrl:'http://localhost:8181/root/code?time='+new Date(),
Define the method resetImg() of clicking to replace the verification code image. Because imgUrl itself is random, here you can directly refresh the verification code image by re creating a random imgUrl
resetImg(){ this.imgUrl = "http://localhost:8181/root/code?time="+new Date(); }
Request login authentication
The interface request for submitting the login form is attached here, and the code parameter is passed to the back-end verification to realize login
If res.data Message is code error!, Indicates a code verification error, throws a message to prompt the verification code error, and resets imgUrl to refresh the verification code picture
_this.axios.post('/root/login', {root_name: this.loginForm.root_name, root_password: this.loginForm.root_password, code: this.loginForm.code}, {'Content-Type': 'application/json; charset=utf-8'} ).then(res => { console.log(res); if (res.data.message === 'code error!'){ _this.$message.error('Verification code error!'); _this.imgUrl= "http://localhost:8181/root/code?time=" +new Date();} else if (res.data.message === 'login error!'){ _this.$message .error('The user name or password is incorrect. Please log in again!');} else { //Save session sessionStorage.setItem('root_name', _this.loginForm.root_name); sessionStorage.setItem('root_password', _this.loginForm.root_password); sessionStorage.setItem('root_img', res.data.root_img); sessionStorage.setItem("root_token",res.data.token); _this.$message({ message: 'Login succeeded!', type: 'success', }); _this.$router.push({path:'/home'});} }