目前我们使用的web系统在登陆功能开发时,不仅仅只是单纯的使用表单填写用户注册信息来进行注册,参考我们现在使用的其他软件存在以下登录情况。
常见的就是着两种登录方式,他们使用的频率比单纯的表单填写信息更加的美观。
注意:我们这篇文章只是让我们了解第三方平台账号授权和手机验证码,在此不过多关注和区分登录和注册的逻辑。
进入QQ互联—>点击头像填写个人信息—>应用管理
(审核需要一定的时间)可以参考QQ互联文档资料
2.1添加依赖
我们再springboot实现该功能
org.apache.commons
commons-io
1.3.2
org.apache.commons
commons-lang3
org.apache.httpcomponents
httpclient
com.alibaba
fastjson
1.2.38
2.2配置文件信息
填写QQ互联的Appid,key,登录后回调地址(必须和QQ互联填写的一致,QQLogin 对应代码里的接口)
constants.qqAppId=101513767
constants.qqAppSecret=b1d978cefcf405388893d8e686d307b0
constants.qqRedirectUrl=http://127.0.0.1:8080/QQLogin
2.3读取配置信息类
@Component
public class Constants {
@Value("${constants.qqAppId}")
private String qqAppId;
@Value("${constants.qqAppSecret}")
private String qqAppSecret;
@Value("${constants.qqRedirectUrl}")
private String qqRedirectUrl;
@Value("${constants.weCatAppId}")
private String weCatAppId;
@Value("${constants.weCatAppSecret}")
private String weCatAppSecret;
@Value("${constants.weCatRedirectUrl}")
private String weCatRedirectUrl;
//自行生成set get方法
}
2.4QQ数据实体类
QQ将把返回的信息封装到这里
public class QQUserInfo {
private Integer ret;
private String msg;
private Integer is_lost;
private String nickname;
private String gender;
private String province;
private String city;
private String year;
private String constellation;
private String figureurl;
private String figureurl_1;
private String figureurl_2;
private String figureurl_qq;
private String figureurl_qq_1;
private String figureurl_qq_2;
private String is_yellow_vip;
private String vip;
private String yellow_vip_level;
private String level;
private String is_yellow_year_vip;
//自行生成 set get
}
2.5http工具类 HttpClientUtils
public class HttpClientUtils {
public static final int connTimeout = 10000;
public static final int readTimeout = 10000;
public static final String charset = "UTF-8";
private static HttpClient client = null;
static {
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
cm.setMaxTotal(128);
cm.setDefaultMaxPerRoute(128);
client = HttpClients.custom().setConnectionManager(cm).build();
}
public static String postParameters(String url, String parameterStr)
throws ConnectTimeoutException, SocketTimeoutException, Exception {
return post(url, parameterStr, "application/x-www-form-urlencoded", charset, connTimeout, readTimeout);
}
public static String postParameters(String url, String parameterStr, String charset, Integer connTimeout,
Integer readTimeout) throws ConnectTimeoutException, SocketTimeoutException, Exception {
return post(url, parameterStr, "application/x-www-form-urlencoded", charset, connTimeout, readTimeout);
}
public static String postParameters(String url, Map params)
throws ConnectTimeoutException, SocketTimeoutException, Exception {
return postForm(url, params, null, connTimeout, readTimeout);
}
public static String postParameters(String url, Map params, Integer connTimeout,
Integer readTimeout) throws ConnectTimeoutException, SocketTimeoutException, Exception {
return postForm(url, params, null, connTimeout, readTimeout);
}
public static String get(String url) throws Exception {
return get(url, charset, null, null);
}
public static String get(String url, String charset) throws Exception {
return get(url, charset, connTimeout, readTimeout);
}
/**
* 发送一个 Post 请求, 使用指定的字符集编码.
*
* @param url
* @param body RequestBody
* @param mimeType 例如 application/xml "application/x-www-form-urlencoded"
* a=1&b=2&c=3
* @param charset 编码
* @param connTimeout 建立链接超时时间,毫秒.
* @param readTimeout 响应超时时间,毫秒.
* @return ResponseBody, 使用指定的字符集编码.
* @throws ConnectTimeoutException 建立链接超时异常
* @throws SocketTimeoutException 响应超时
* @throws Exception
*/
public static String post(String url, String body, String mimeType, String charset, Integer connTimeout,
Integer readTimeout) throws ConnectTimeoutException, SocketTimeoutException, Exception {
HttpClient client = null;
HttpPost post = new HttpPost(url);
String result = "";
try {
if (StringUtils.isNotBlank(body)) {
HttpEntity entity = new StringEntity(body, ContentType.create(mimeType, charset));
post.setEntity(entity);
}
// 设置参数
Builder customReqConf = RequestConfig.custom();
if (connTimeout != null) {
customReqConf.setConnectTimeout(connTimeout);
}
if (readTimeout != null) {
customReqConf.setSocketTimeout(readTimeout);
}
post.setConfig(customReqConf.build());
HttpResponse res;
if (url.startsWith("https")) {
// 执行 Https 请求.
client = createSSLInsecureClient();
res = client.execute(post);
} else {
// 执行 Http 请求.
client = HttpClientUtils.client;
res = client.execute(post);
}
result = IOUtils.toString(res.getEntity().getContent(), charset);
} finally {
post.releaseConnection();
if (url.startsWith("https") && client != null && client instanceof CloseableHttpClient) {
((CloseableHttpClient) client).close();
}
}
return result;
}
/**
* 提交form表单
*
* @param url
* @param params
* @param connTimeout
* @param readTimeout
* @return
* @throws ConnectTimeoutException
* @throws SocketTimeoutException
* @throws Exception
*/
public static String postForm(String url, Map params, Map headers,
Integer connTimeout, Integer readTimeout)
throws ConnectTimeoutException, SocketTimeoutException, Exception {
HttpClient client = null;
HttpPost post = new HttpPost(url);
try {
if (params != null && !params.isEmpty()) {
List formParams = new ArrayList();
Set> entrySet = params.entrySet();
for (Map.Entry entry : entrySet) {
formParams.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
}
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formParams, Consts.UTF_8);
post.setEntity(entity);
}
if (headers != null && !headers.isEmpty()) {
for (Map.Entry entry : headers.entrySet()) {
post.addHeader(entry.getKey(), entry.getValue());
}
}
// 设置参数
Builder customReqConf = RequestConfig.custom();
if (connTimeout != null) {
customReqConf.setConnectTimeout(connTimeout);
}
if (readTimeout != null) {
customReqConf.setSocketTimeout(readTimeout);
}
post.setConfig(customReqConf.build());
HttpResponse res = null;
if (url.startsWith("https")) {
// 执行 Https 请求.
client = createSSLInsecureClient();
res = client.execute(post);
} else {
// 执行 Http 请求.
client = HttpClientUtils.client;
res = client.execute(post);
}
return IOUtils.toString(res.getEntity().getContent(), "UTF-8");
} finally {
post.releaseConnection();
if (url.startsWith("https") && client != null && client instanceof CloseableHttpClient) {
((CloseableHttpClient) client).close();
}
}
}
/**
* 发送一个 GET 请求
*
* @param url
* @param charset
* @param connTimeout 建立链接超时时间,毫秒.
* @param readTimeout 响应超时时间,毫秒.
* @return
* @throws ConnectTimeoutException 建立链接超时
* @throws SocketTimeoutException 响应超时
* @throws Exception
*/
public static String get(String url, String charset, Integer connTimeout, Integer readTimeout)
throws ConnectTimeoutException, SocketTimeoutException, Exception {
HttpClient client = null;
HttpGet get = new HttpGet(url);
String result = "";
try {
// 设置参数
Builder customReqConf = RequestConfig.custom();
if (connTimeout != null) {
customReqConf.setConnectTimeout(connTimeout);
}
if (readTimeout != null) {
customReqConf.setSocketTimeout(readTimeout);
}
get.setConfig(customReqConf.build());
HttpResponse res = null;
if (url.startsWith("https")) {
// 执行 Https 请求.
client = createSSLInsecureClient();
res = client.execute(get);
} else {
// 执行 Http 请求.
client = HttpClientUtils.client;
res = client.execute(get);
}
result = IOUtils.toString(res.getEntity().getContent(), charset);
} finally {
get.releaseConnection();
if (url.startsWith("https") && client != null && client instanceof CloseableHttpClient) {
((CloseableHttpClient) client).close();
}
}
return result;
}
/**
* 从 response 里获取 charset
*
* @param ressponse
* @return
*/
@SuppressWarnings("unused")
private static String getCharsetFromResponse(HttpResponse ressponse) {
// Content-Type:text/html; charset=GBK
if (ressponse.getEntity() != null && ressponse.getEntity().getContentType() != null
&& ressponse.getEntity().getContentType().getValue() != null) {
String contentType = ressponse.getEntity().getContentType().getValue();
if (contentType.contains("charset=")) {
return contentType.substring(contentType.indexOf("charset=") + 8);
}
}
return null;
}
/**
* 创建 SSL连接
*
* @return
* @throws GeneralSecurityException
*/
private static CloseableHttpClient createSSLInsecureClient() throws GeneralSecurityException {
try {
SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
return true;
}
}).build();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, new X509HostnameVerifier() {
@Override
public boolean verify(String arg0, SSLSession arg1) {
return true;
}
@Override
public void verify(String host, SSLSocket ssl) throws IOException {
}
@Override
public void verify(String host, X509Certificate cert) throws SSLException {
}
@Override
public void verify(String host, String[] cns, String[] subjectAlts) throws SSLException {
}
});
return HttpClients.custom().setSSLSocketFactory(sslsf).build();
} catch (GeneralSecurityException e) {
throw e;
}
}
public static void main(String[] args) {
try {
String str = post("https://localhost:443/ssl/test.shtml", "name=12&page=34",
"application/x-www-form-urlencoded", "UTF-8", 10000, 10000);
// String str=
// get("https://localhost:443/ssl/test.shtml?name=12&page=34","GBK");
/*
* Map map = new HashMap(); map.put("name",
* "111"); map.put("page", "222"); String str=
* postForm("https://localhost:443/ssl/test.shtml",map,null, 10000, 10000);
*/
System.out.println(str);
} catch (ConnectTimeoutException e) {
e.printStackTrace();
} catch (SocketTimeoutException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
2.6url转码工具类 URLEncodeUtil
不管是以何种方式传递url时,如果要传递的url中包含特殊字符,如想要传递一个+,但是这个+会被url会被编码成空格,想要传递&,被url处理成分隔符。所以都会做一下url转码的工作。
public class URLEncodeUtil {
private final static String ENCODE = "UTF-8";
/**
* URL 解码
*/
public static String getURLDecoderString(String str) {
String result = "";
if (null == str) {
return "";
}
try {
result = java.net.URLDecoder.decode(str, ENCODE);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return result;
}
/**
* URL 转码
*/
public static String getURLEncoderString(String str) {
String result = "";
if (null == str) {
return "";
}
try {
result = java.net.URLEncoder.encode(str, ENCODE);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return result;
}
}
2.7全段页面
Insert title here
获取qq登录连接
开始登录
跳到微信登录页
2.8效果
授权后返回的信息
短信登陆可以参考:微信开放平台官方文档
我们使用阿里云短信服务来完成发送验证码
进去阿里云,搜索短信服务,完成学习应该就了解的差不多了
1.添加签名和模板
2.获取自己的阿里云私匙
可以参考OpenAPI Explorer