提到登录验证,大家肯定能想到的就是12306的验证码了吧。12306为了防止刷票,可以说是煞费苦心,验证码也越来越难识别,最终即使是人也可能识别不了了。
今天,小编就给大家说一下node如何实现图片验证码,以及使用token验证登录。学习本文你将学到:
1.使用captchapng生成图片验证码
2.使用jsonwebtoken实现登录验证
一、图片验证码生成(最后有全部代码)
首先,我们理一下流程,第一步服务器要随机生成一组四位数。
第二步,将这四位数用canvas绘图生成图片。
第三步,我们要将这四位数存起来,以便用户返回数据时做对比。
那么存到哪里呢?很明显为了区分用户,存到session最为稳妥。
第一步,先要有一个登录页面。在这里我们依然用react,
login.tsx
import * as React from 'react' import * as ReactDom from 'react-dom' import {Link, browserHistory} from 'react-router'; import * as axios from 'axios'; export default class Login extends React.Component<any,any>{ constructor(props){ super(props) this.state = { userName : '', password : '', yzNoId : '', hash : Math.random() } } handleUserName(e) : any { this.setState({ userName : e.target.value }) } handlePassword(e) : any { this.setState({ password : e.target.value }) } handleYzId(e) : any { this.setState({ yzNoId : e.target.value }) } render(){ const { userName, password, yzNoId } = this.state; return( <div> <div className="nav-wrap"> <ul className="nav"> <li><Link to="/home">首页</Link></li> <li><Link to="/imgLoad">上传</Link></li> <li><Link to="/login">登陆</Link></li> </ul> </div> <div className="content"> <div className="login-warp"> <p> <input type="text" className="username" value=https://www.jb51.net/article/{userName} onChange=https://www.jb51.net/article/{this.handleUserName.bind(this)} placeholder="用户名"/> </p> <p> <input type="text" className="password" value=https://www.jb51.net/article/{password} onChange=https://www.jb51.net/article/{this.handlePassword.bind(this)} placeholder="密码"/> </p> <p> <input type="text" className="yz" value=https://www.jb51.net/article/{yzNoId} onChange=https://www.jb51.net/article/{this.handleYzId.bind(this)} placeholder="验证码"/> <img src=https://www.jb51.net/article/{"http://localhost:3000/captcha"} className="yz-img" /> </p> <p> <input type="button" className="submit" value="登陆" onClick=https://www.jb51.net/article/{this.sbumit.bind(this,{userName:userName,password:password,captcha:yzNoId})} /> </p> </div> </div> </div> ) } }
页面是这样的
我们需要通过服务器给一张验证图片。
router/index.js 添加如下代码
var Login = require('./controller/login'); var login = new Login; router.get('/captcha', login.captcha); router.post('/login',login.loginer); login是定义在控制器的一个类的实例,captcha,loginer是它的方法。分别是返回验证图片、登录验证。 controller/login.js var rf = require('fs'); var captchapng = require('captchapng'); class Login { constructor(){} captcha(req, res, next) { var str = parseInt(Math.random()*9000+1000); //随机生成数字 req.session.captcha = str; // 存入session var p = new captchapng(80, 30, str); //生成图片 p.color(0, 0, 0, 0); p.color(80, 80, 80, 255); var img = p.getBase64(); var imgbase64 = new Buffer(img, 'base64'); res.writeHead(200, { 'Content-Type': 'image/png' }); res.end(imgbase64); } loginer(req, res, next) { let captcha = req.body.captcha; let userName = req.body.userName; let password = req.body.password; if (captcha != req.session.captcha) { res.status(400).send({ message: '验证码错误' }); }else if(userName == "chenxuehui" && password == "123321"){ res.json({"code":100,"verson":true,"msg":"登陆成功","token":token}); }else{ res.json({"code":0,"verson":false,"msg":"密码错误"}); } } } module.exports = Login
captcha方法是生成一张含四位数字的图片,然后将图片保存到session中。
将此方法在 router/index.js 中引用
router.get('/captcha', login.captcha);
也就是说我们访问localhost:3000/captcha就会返回一张图片。
有了这个连接后我们就可以通过图片的src属性拿到该图片,但是当点击图片的时候要重新刷新,所以我们需要给图片添加一个点击刷新事件。将下面代码插入到login.tsx中
setHash() { this.setState({ hash : Math.random() }) }
img标签也变成了
复制代码 代码如下:
<img src=https://www.jb51.net/article/{"} className="yz-img" onClick=https://www.jb51.net/article/{this.setHash.bind(this)} />
此时login.tsx全部代码: