注册功能之手机验证与邮箱验证
这两天尝试写了一个注册功能,一种是手机验证码注册,一种是邮箱注册激活。开始写的时候,不知道从哪着手,看了好几篇文章,开始慢慢了解思路,现在就记录下来。
思路:
注册之手机验证:一个注册页面【手机号框、验证码框、点击获取验证码按钮、点击注册按钮】。点击获取验证码后,后台controller层随机生成一个6位随机数(即验证码),把验证码通过某个短信API接口传到该手机上。手机信息看到验证码,就把它输入前台的验证码框,点注册提交,只要输入的验证码与后台生成的验证码是相同的,就可以提示注册成功了。
注册之邮箱激活:一个注册页面【用户名框、密码框、邮箱框、点击注册按钮】。一个数据库【用户表:id、username、password、state(激活码状态)、code(激活码)】。一个后台默认生成一个激活码(可以用UUID)和默认一个激活码状态(比如:“0”)。用户在点击注册后,将数据保存在数据库,保存成功后,新建一个线程去执行发送邮件的任务,通过邮箱发送一个带code(激活码)的链接给用户,用户点击链接后,后台接收到链接传过来的激活码,查询数据库是否存在该用户信息,有则执行修改激活码状态(比如“1”),然后提示注册成功。
代码之手机验证(测试):我是申请聚合数据的短信API接口来用的(参考其开发文档),其他也行吧,这里只测试发验证码给手机。
package com.fh.controller.system.SMS; import net.sf.json.JSONObject; import java.util.HashMap; import java.util.Map; import java.util.Random; import static com.fh.util.url.UrlUtil.net; public class SmsVerification { public static void main(String[] args) {
//这个这样写主要是开发文档里这样规定 String code ="#code#="+getCode();
String result =null; String url ="http://v.juhe.cn/sms/send";//请求接口地址 Map params = new HashMap();//请求参数 params.put("mobile","*******");//接受短信的用户手机号码 params.put("tpl_id","*******");//您申请的短信模板ID,根据实际情况修改 params.put("tpl_value",code);//您设置的模板变量,根据实际情况修改 params.put("key","*****************");//应用APPKEY(应用详细页查询) try { result = net(url, params, "GET"); JSONObject object = JSONObject.fromObject(result); if(object.getInt("error_code")==0){ System.out.println(object.get("result")); }else{ System.out.println(object.get("error_code")+":"+object.get("reason")); } } catch (Exception e) { e.printStackTrace(); } } //获取随机验证码 public static String getCode(){ //开始生成随机数字 -- 验证码 StringBuffer buffer = new StringBuffer(); Random random = new Random(); //随机数字 for(int i =0;i<6 ;i++) { //生成一个6位数的随机数 buffer.append(random.nextInt(10));//范围0到10,不包括10 ;0-9 } return buffer.toString(); } }
工具类(这里只用到net方法)
package com.fh.util.url;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.Map;
public class UrlUtil {
public static final String DEF_CHATSET = "UTF-8";
public static final int DEF_CONN_TIMEOUT = 30000;
public static final int DEF_READ_TIMEOUT = 30000;
public static String userAgent = "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.66 Safari/537.36";
// 配置您申请的KEY
public static final String APPKEY = "*************************";
/**
* 向指定的地址发送一个post请求,带着data数据
*
* @param url
* @param data
* @return by 罗召勇 Q群193557337
*/
public static String post(String url, String data) {
try {
URL urlObj = new URL(url);
URLConnection connection = urlObj.openConnection();
// 要发送数据出去,必须要设置为可发送数据状态
connection.setDoOutput(true);
// 获取输出流
OutputStream os = connection.getOutputStream();
// 写出数据
os.write(data.getBytes());
os.close();
// 获取输入流
InputStream is = connection.getInputStream();
byte[] b = new byte[1024];
int len;
StringBuilder sb = new StringBuilder();
while ((len = is.read(b)) != -1) {
sb.append(new String(b, 0, len));
}
return sb.toString();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 向指定的地址发送get请求
*
* @param url
* @return by 罗召勇 Q群193557337
*/
public static String get(String url) {
try {
URL urlObj = new URL(url);
// 开连接
URLConnection connection = urlObj.openConnection();
InputStream is = connection.getInputStream();
byte[] b = new byte[1024];
int len;
StringBuilder sb = new StringBuilder();
while ((len = is.read(b)) != -1) {
sb.append(new String(b, 0, len));
}
return sb.toString();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
*
* @param strUrl
* 请求地址
* @param params
* 请求参数
* @param method
* 请求方法
* @return 网络请求字符串
* @throws Exception
*/
public static String net(String strUrl, Map params, String method) throws Exception {
HttpURLConnection conn = null;
BufferedReader reader = null;
String rs = null;
try {
StringBuffer sb = new StringBuffer();
if (method == null || method.equals("GET")) {
strUrl = strUrl + "?" + urlencode(params);
}
URL url = new URL(strUrl);
conn = (HttpURLConnection) url.openConnection();
if (method == null || method.equals("GET")) {
conn.setRequestMethod("GET");
} else {
conn.setRequestMethod("POST");
conn.setDoOutput(true);
}
conn.setRequestProperty("User-agent", userAgent);
conn.setUseCaches(false);
conn.setConnectTimeout(DEF_CONN_TIMEOUT);
conn.setReadTimeout(DEF_READ_TIMEOUT);
conn.setInstanceFollowRedirects(false);
conn.connect();
if (params != null && method.equals("POST")) {
try {
DataOutputStream out = new DataOutputStream(conn.getOutputStream());
out.writeBytes(urlencode(params));
} catch (Exception e) {
// TODO: handle exception
}
}
InputStream is = conn.getInputStream();
reader = new BufferedReader(new InputStreamReader(is, DEF_CHATSET));
String strRead = null;
while ((strRead = reader.readLine()) != null) {
sb.append(strRead);
}
rs = sb.toString();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
reader.close();
}
if (conn != null) {
conn.disconnect();
}
}
return rs;
}
// 将map型转为请求参数型
public static String urlencode(Map<String, Object> data) {
StringBuilder sb = new StringBuilder();
for (Map.Entry i : data.entrySet()) {
try {
sb.append(i.getKey()).append("=").append(URLEncoder.encode(i.getValue() + "", "UTF-8")).append("&");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
return sb.toString();
}
}
代码之邮箱注册:需要一个javax.mail.jar包:https://files.cnblogs.com/files/yuanmaolin/javax.mail.zip,红色链接【http://p5up23.natappfree.cc】我是直接用内网穿透来弄的,这样外部就可以访问到我的本地后台。至于邮箱,是需要去打开smtp协议。
package com.fh.util.mailboxactivation; import com.sun.mail.util.MailSSLSocketFactory; import javax.mail.*; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeMessage; import java.util.Properties; public class MailUtil implements Runnable { private String email;// 收件人邮箱 private String code;// 激活码 public MailUtil(String email, String code) { this.email = email; this.code = code; } public void run() { // 1.创建连接对象javax.mail.Session // 2.创建邮件对象 javax.mail.Message // 3.发送一封激活邮件 String from = "********@163.com";// 发件人电子邮箱 String host = "smtp.163.com"; // 指定发送邮件的主机smtp.qq.com(QQ)|smtp.163.com(网易) Properties properties = System.getProperties();// 获取系统属性 properties.setProperty("mail.smtp.host", host);// 设置邮件服务器 properties.setProperty("mail.smtp.auth", "true");// 打开认证 try { //QQ邮箱需要下面这段代码,163邮箱不需要 /*MailSSLSocketFactory sf = new MailSSLSocketFactory(); sf.setTrustAllHosts(true); properties.put("mail.smtp.ssl.enable", "true"); properties.put("mail.smtp.ssl.socketFactory", sf);*/ // 1.获取默认session对象 Session session = Session.getDefaultInstance(properties, new Authenticator() { public PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication("*********@163.com", "*******"); // 发件人邮箱账号、授权码 } }); // 2.创建邮件对象 Message message = new MimeMessage(session); // 2.1设置发件人 message.setFrom(new InternetAddress(from)); // 2.2设置接收人 message.addRecipient(Message.RecipientType.TO, new InternetAddress(email)); // 2.3设置邮件主题 message.setSubject("账号激活"); // 2.4设置邮件内容 String content = "<html>" + "<head></head>" + "<body>" + "<h1>这是一封激活邮件,激活请点击以下链接</h1>" + "<h3><a href='http://p5up23.natappfree.cc/mailbox/active?code=" + code + "'>" + "http://p5up23.natappfree.cc/mailbox/active?code=" + code + "</href>" + "</h3>" + "</body>" + "</html>"; message.setContent(content, "text/html;charset=UTF-8"); // 3.发送邮件 Transport.send(message); System.out.println("邮件成功发送!"); } catch (Exception e) { e.printStackTrace(); } } }
测试邮箱发送
import com.fh.util.mailboxactivation.MailUtil; public class test { public static void main(String[] args) { String mail = "*******@qq.com"; String code = "dhfjgkridujfhng"; //这里只是测试,我就没新建一个线程了,实际可以这样【new Thread(new MailUtil(mail, code)).start();】 MailUtil(mail, code); } }
后面就是查看邮箱,点击链接,后台接收code。。。。按上面思路来。