登錄方式
- 微信開放平臺(tái)登錄
- 微信公眾號(hào)登錄
賬號(hào)體系
- 沒有自己的賬號(hào)體系,直接拉取用戶信息來授權(quán)登錄
- 有自己的賬號(hào)體系,授權(quán)成功后需要綁定自己的賬號(hào)
微信網(wǎng)頁(yè)授權(quán)官方開發(fā)文檔
網(wǎng)頁(yè)授權(quán)流程
- 引導(dǎo)用戶進(jìn)入授權(quán)頁(yè)面同意授權(quán)粘勒,獲取code
- 通過code換取網(wǎng)頁(yè)授權(quán)access_token(與基礎(chǔ)支持中的access_token不同)
- 如果需要舱痘,開發(fā)者可以刷新網(wǎng)頁(yè)授權(quán)access_token,避免過期
- 通過網(wǎng)頁(yè)授權(quán)access_token和openid獲取用戶基本信息(支持UnionID機(jī)制)
這里以微信公眾號(hào)授權(quán)流程為例
微信公眾號(hào)測(cè)試號(hào)申請(qǐng)
針對(duì)普通開發(fā)者莫其,無需申請(qǐng)公眾賬號(hào)魂迄、可在測(cè)試賬號(hào)中體驗(yàn)并測(cè)試微信公眾平臺(tái)所有高級(jí)接口粗截。
申請(qǐng)網(wǎng)址: 微信公眾號(hào)測(cè)試號(hào)申請(qǐng)
Java和Maven環(huán)境
前提:
系統(tǒng)已經(jīng)配置好Java和Maven環(huán)境(Windows環(huán)境下具體怎么配置可以參考百度上的教程,這個(gè)有很多)捣炬。這里我用的Java版本是1.8熊昌,Maven版本是3.6.1
測(cè)試:
通過運(yùn)行(Windows+R)绽榛,輸入cmd打開Dos命令環(huán)境。輸入javac
打印出一系列用法提示和輸入mvn -v
打印出Maven版本代表環(huán)境配置成功婿屹。
配置文件修改:
因?yàn)樵趪?guó)內(nèi)使用Maven默認(rèn)的遠(yuǎn)程倉(cāng)庫(kù)地址下載的比較慢灭美,所以一般都會(huì)換成國(guó)內(nèi)的淘寶鏡像。
找到maven安裝路徑下的conf文件夾里的settings.xml
文件
打開昂利,修改鏡像地址為
<mirrors>
<mirror>
<id>alimaven</id>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<mirrorOf>central</mirrorOf>
</mirror>
</mirrors>
同時(shí)一并替換了本地倉(cāng)庫(kù)地址,因?yàn)槟J(rèn)倉(cāng)庫(kù)地址在C盤,時(shí)間久了包會(huì)越來越多,占用C盤空間
<localRepository>你的非C盤地址</localRepository>
使用Idea創(chuàng)建Maven工程
在Idea中新建工程届腐,選擇Maven工程,創(chuàng)建web-app的archetype
選擇好了后蜂奸,下一步犁苏。根據(jù)下圖中提示配置項(xiàng)目信息。
下一步
點(diǎn)擊Finish扩所。首次創(chuàng)建Maven會(huì)從遠(yuǎn)程倉(cāng)庫(kù)開始下jar包围详,需要等待一會(huì)兒。
maven自動(dòng)執(zhí)行完成后,你的項(xiàng)目根目錄中就會(huì)有pom.xml
這個(gè)文件,可以把這個(gè)文件理解為前端項(xiàng)目中的package.json
文件,主要用于映射遠(yuǎn)程倉(cāng)庫(kù)的包,配置完后,運(yùn)行maven命令會(huì)自動(dòng)幫你下包(此處注意Idea右下角提示碌奉,選擇自動(dòng)運(yùn)行導(dǎo)包),配置如下(主要是引入Junit測(cè)試和http訪問,以及一些maven插件)
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.hzmeurasia</groupId>
<artifactId>WxAuth</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>WxAuth Maven Webapp</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.5</version>
</dependency>
<dependency>
<groupId>com.hynnet</groupId>
<artifactId>json-lib</artifactId>
<version>2.4</version>
</dependency>
</dependencies>
<build>
<finalName>WxAuth</finalName>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.2</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
配置Tomcat服務(wù)器
下載:
進(jìn)入官網(wǎng)短曾,選擇Tomcat 8.5.50版本進(jìn)行下載。https://tomcat.apache.org/download-80.cgi
注:最好下載Tomcat7或8的版本赐劣,版本太新出錯(cuò)不好調(diào)試
Tomcat的手動(dòng)啟動(dòng)和關(guān)閉
下載完成后,直接解壓哩都。找到bin目錄下的startup.bat
和shutdown.bat
魁兼,分別用于手動(dòng)打開和關(guān)閉Tomcat服務(wù)。
雙擊startup.bat
漠嵌,打開瀏覽器地址欄輸入:http://localhost:8080/
咐汞,能顯示出Tomcat默認(rèn)網(wǎng)頁(yè)就表示成功
Tomcat環(huán)境變量配置
安裝完成后,右擊我的電腦
儒鹿,點(diǎn)擊屬性
化撕,選擇高級(jí)系統(tǒng)設(shè)置
,點(diǎn)擊環(huán)境變量
在系統(tǒng)變量
中添加
變量名:CATALINA_BASE
變量值:D:\Tomcat\apache-tomcat-8.5.50 (Tomcat安裝目錄)
變量名:CATALINA_HOME
變量值:同Tomcat安裝目錄
修改ClassPath
和Path
變量
ClassPath變量值加入:%CATALINA_HOME%\lib\servlet-api.jar;
Path變量加入:%CATALINA_HOME%\bin;
和%CATALINA_HOME%\lib
點(diǎn)擊確定约炎,Tomcat就配置好了植阴。
驗(yàn)證:
點(diǎn)擊"開始"->"運(yùn)行",鍵入"cmd"(或快捷鍵win+R)圾浅;鍵入命令:startup
掠手,出現(xiàn)以下信息,說明環(huán)境變量配置成功
關(guān)閉窗口狸捕,即可關(guān)閉Tomcat服務(wù)
Idea配置Tomcat
打開剛才創(chuàng)建的Maven項(xiàng)目喷鸽,點(diǎn)擊Run---Edit Configurations...
點(diǎn)擊左側(cè)“+”號(hào),找到Tomcat Server---Local
(若是沒有找到Tomcat Server 可以點(diǎn)擊最后一行 34 items more)
在Tomcat Server -> Unnamed -> Server -> Application server項(xiàng)目下灸拍,點(diǎn)擊 Configuration 做祝,找到本地 Tomcat 服務(wù)器砾省,再點(diǎn)擊 OK按鈕。
這里尤其要注意一下端口號(hào)混槐,建議先填80端口编兄。如果要修改端口號(hào),之后在微信的回調(diào)域名的必須要加上端口號(hào)纵隔,因?yàn)槲⑿攀跈?quán)默認(rèn)回調(diào)域名端口號(hào)為80端口
引入servlet的api
點(diǎn)擊項(xiàng)目右上角打開工程結(jié)構(gòu)的按鈕
選擇Library翻诉,如圖所示添加
選擇Tomcat安裝路徑下的lib中的
servlet-api.jar
之后一路點(diǎn)Ok,完成捌刮。
配置內(nèi)網(wǎng)穿透
內(nèi)網(wǎng)穿透碰煌,即NAT穿透,網(wǎng)絡(luò)連接時(shí)術(shù)語(yǔ)绅作,計(jì)算機(jī)是局域網(wǎng)內(nèi)時(shí)芦圾,外網(wǎng)與內(nèi)網(wǎng)的計(jì)算機(jī)節(jié)點(diǎn)需要連接通信,有時(shí)就會(huì)出現(xiàn)不支持內(nèi)網(wǎng)穿透俄认。就是說映射端口个少,能讓外網(wǎng)的電腦找到處于內(nèi)網(wǎng)的電腦
本文中采用的是NATAPP提供的內(nèi)網(wǎng)穿透服務(wù),作為案例眯杏。
NATAPP官網(wǎng): https://natapp.cn/
NATAPP1分鐘快速新手圖文教程:https://natapp.cn/article/natapp_newbie
參考以上教程夜焦,從官網(wǎng)下載客戶端,得到natapp.exe
運(yùn)行程序
windows ,點(diǎn)擊開始->運(yùn)行->命令行提示符 后進(jìn)入 natapp.exe的目錄
運(yùn)行 natapp -authtoken=你的密鑰
運(yùn)行成功,都可以得到如下界面:
做完了這些配置信息后岂贩,就可以開始正式寫代碼了茫经。
配置工具類
在src/main/java/com/wx/auth/util下新建AuthUtil.java文件,寫網(wǎng)絡(luò)請(qǐng)求訪問工具方法萎津,例:
package com.wx.auth.util;
import net.sf.json.JSONObject;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.util.EntityUtils;
import javax.net.ssl.SSLContext;
import java.io.IOException;
/**
* @author HZM
* @className AuthUtil
* @description 微信授權(quán)網(wǎng)絡(luò)請(qǐng)求工具類
* @date 2019/12/29 20:56
**/
public class AuthUtil {
public static final String APPID = "wxbdcb94341d5c7aa4";
public static final String APPSECRET = "1a4b4530dcbe3a0b0a65e58636bd93c6";
public static JSONObject doGetJson(String url) throws IOException {
JSONObject jsonObject = null;
HttpGet httpGet = new HttpGet(url);
HttpResponse response = httpClient.execute(httpGet);
HttpEntity entity = response.getEntity();
if (entity != null) {
String result = EntityUtils.toString(entity, "UTF-8");
jsonObject = JSONObject.fromObject(result);
}
// 釋放鏈接
httpGet.releaseConnection();
return jsonObject;
}
/**
* 忽略https證書
*/
private static CloseableHttpClient httpClient;
//jdk1.8用此代碼
static {
try {
SSLContext sslContext = SSLContextBuilder.create().useProtocol(SSLConnectionSocketFactory.SSL).loadTrustMaterial((x, y) -> true).build();
RequestConfig config = RequestConfig.custom().setConnectTimeout(5000).setSocketTimeout(5000).build();
httpClient = HttpClientBuilder.create().setDefaultRequestConfig(config).setSSLContext(sslContext).setSSLHostnameVerifier((x, y) -> true).build();
} catch (Exception e) {
e.printStackTrace();
}
}
}
APPID和APPSECRET在微信公眾號(hào)測(cè)試號(hào)網(wǎng)頁(yè)獲取
微信校驗(yàn)第一步:用戶同意授權(quán)卸伞,獲取code
微信網(wǎng)頁(yè)授權(quán)開發(fā)文檔
首先公眾號(hào)需具備網(wǎng)頁(yè)H5授權(quán)權(quán)限,我們?cè)谖恼麻_頭申請(qǐng)的微信公眾號(hào)測(cè)試號(hào)已具備H5授權(quán)權(quán)限锉屈。
之后荤傲,要引導(dǎo)用戶跳轉(zhuǎn)到微信指定的網(wǎng)頁(yè)并配置回調(diào)地址。
在src/main/java/com/wx/auth/servlet下新建LoginServelet.java文件颈渊,例:
package com.wx.auth.servlet;
import com.wx.auth.util.AuthUtil;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
/**
* @author HZM
* @className LoginServlet
* @description 登錄驗(yàn)證
* @date 2019/12/29 21:05
**/
@WebServlet("/wxLogin")
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 回調(diào)地址
String backUrl = "http://8dfh4m.natappfree.cc/WxAuth/wxCallBack";
String url = "https://open.weixin.qq.com/connect/oauth2/authorize?" +
"appid=" + AuthUtil.APPID +
"&redirect_uri=" + URLEncoder.encode(backUrl) +
"&response_type=code" +
"&scope=snsapi_userinfo" +
"&state=STATE#wechat_redirect";
resp.sendRedirect(url);
}
}
此處注意參數(shù)順序遂黍,因?yàn)槲⑿诺牡刂肥菍?duì)傳參順序正則強(qiáng)校驗(yàn)。
回調(diào)地址的域名是我們之前開啟NATAPP服務(wù)得到的公網(wǎng)地址
微信校驗(yàn)第二步:通過code換取網(wǎng)頁(yè)授權(quán)access_token
在src/main/java/com/wx/auth/servlet下新建CallBackServelet.java文件儡炼,例:
package com.wx.auth.servlet;
import com.wx.auth.util.AuthUtil;
import net.sf.json.JSONObject;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.sql.*;
/**
* @author HZM
* @className CallBackServlet
* @description 授權(quán)回調(diào)
* @date 2019/12/29 22:08
**/
public class CallBackServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 取到返回的code
String code = req.getParameter("code");
String url = "https://api.weixin.qq.com/sns/oauth2/access_token?" +
"appid=" + AuthUtil.APPID +
"&secret=" + AuthUtil.APPSECRET +
"&code=" + code +
"&grant_type=authorization_code";
JSONObject jsonObject = AuthUtil.doGetJson(url);
String openid = jsonObject.getString("openid");
String token = jsonObject.getString("access_token");
}
微信校驗(yàn)第三步:刷新access_token(如果需要)
這里我們不需要刷新token妓湘,如果需要大家可看官網(wǎng)文檔。
微信校驗(yàn)第四步:拉取用戶信息(需scope為 snsapi_userinfo)
對(duì)第二步的CallBackServelet.java代碼進(jìn)行擴(kuò)充乌询,用獲取到的token換取用戶信息榜贴,例:
package com.wx.auth.servlet;
import com.wx.auth.util.AuthUtil;
import net.sf.json.JSONObject;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.sql.*;
/**
* @author HZM
* @className CallBackServlet
* @description 授權(quán)回調(diào)
* @date 2019/12/29 22:08
**/
public class CallBackServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 取到返回的code
String code = req.getParameter("code");
String url = "https://api.weixin.qq.com/sns/oauth2/access_token?" +
"appid=" + AuthUtil.APPID +
"&secret=" + AuthUtil.APPSECRET +
"&code=" + code +
"&grant_type=authorization_code";
JSONObject jsonObject = AuthUtil.doGetJson(url);
String openid = jsonObject.getString("openid");
String token = jsonObject.getString("access_token");
String infoUrl = "https://api.weixin.qq.com/sns/userinfo?" +
"access_token=" + token +
"&openid=" + openid +
"&lang=zh_CN";
JSONObject userInfo = AuthUtil.doGetJson(infoUrl);
System.out.println(userInfo);
// 情況1:直接使用微信用戶信息直接登錄,無需注冊(cè)和綁定
req.setAttribute("info", userInfo);
req.getRequestDispatcher("/loginSuccess.jsp").forward(req, resp);
}
配置入口和成功頁(yè)面
在src/main/webapp下新建index.jsp(首次進(jìn)入,網(wǎng)頁(yè)默認(rèn)訪問index.jsp文件)
<%--
Created by IntelliJ IDEA.
User: HZM
Date: 2019/12/29
Time: 22:42
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<head>
<title>微信授權(quán)</title>
</head>
<body style="font-size: 40px;text-align: center">
<a href="/WxAuth/wxLogin">微信公眾號(hào)授權(quán)</a>
</body>
</html>
在src/main/webapp下新建loginSuccess.jsp(這是授權(quán)成功后顯示獲取到的用戶個(gè)人信息頁(yè)面)
<%--
Created by IntelliJ IDEA.
User: HZM
Date: 2019/12/29
Time: 22:42
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%--JSP和Servlet版本導(dǎo)致el功能默認(rèn)關(guān)閉,加入<%@page isELIgnored="false"%>標(biāo)簽手動(dòng)開啟el功能--%>
<%@ page isELIgnored="false"%>
<html>
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<head>
<title>登錄結(jié)果</title>
</head>
<body>
<div>登錄成功</div>
<div>用戶昵稱: ${info.nickname}</div>
<div>用戶頭像: <img src="${info.headimgurl}" style="vertical-align: top" width="100" height="100"></div>
</body>
</html>
最后需要把NATAPP生成的域名在微信公眾號(hào)測(cè)試號(hào)設(shè)置為安全域名
在體驗(yàn)接口權(quán)限表里唬党,找到網(wǎng)頁(yè)服務(wù)項(xiàng)里的網(wǎng)頁(yè)賬號(hào)項(xiàng)鹃共,點(diǎn)擊修改
至此,可以啟動(dòng)Tomcat服務(wù)了驶拱。在Idea工具中可以快捷啟動(dòng)
訪問localhost/WxAuth/出現(xiàn)如下頁(yè)面表示本地項(xiàng)目成功啟動(dòng)霜浴。
訪問項(xiàng)目的線上地址
http://你申請(qǐng)到的臨時(shí)域名/WxAuth/
,如果出現(xiàn)同樣的頁(yè)面表示內(nèi)網(wǎng)穿透成功蓝纲,本地地址已經(jīng)成功映射到線上阴孟。在微信中點(diǎn)擊該鏈接(如果在非微信瀏覽器點(diǎn)擊,授權(quán)時(shí)會(huì)提示“請(qǐng)?jiān)谖⑿旁L問該網(wǎng)頁(yè)”)
首次點(diǎn)擊會(huì)出現(xiàn)是否授權(quán)頁(yè)面税迷。
同意之后永丝,獲取到用戶信息