Idea使用Maven和Tomcat实现微信授权

登录方式

  1. 微信开放平台登录
  2. 微信公众号登录

账号体系

  1. 没有自己的账号体系,直接拉取用户信息来授权登录
  2. 有自己的账号体系,授权成功后需要绑定自己的账号

微信网页授权官方开发文档

微信网页授权

网页授权流程

  1. 引导用户进入授权页面同意授权,获取code
  2. 通过code换取网页授权access_token(与基础支持中的access_token不同)
  3. 如果需要,开发者可以刷新网页授权access_token,避免过期
  4. 通过网页授权access_token和openid获取用户基本信息(支持UnionID机制)

这里以微信公众号授权流程为例

微信公众号授权流程

微信公众号测试号申请

针对普通开发者,无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。

申请网址: 微信公众号测试号申请

Java和Maven环境

前提:

系统已经配置好Java和Maven环境(Windows环境下具体怎么配置可以参考百度上的教程,这个有很多)。这里我用的Java版本是1.8,Maven版本是3.6.1

测试:

通过运行(Windows+R),输入cmd打开Dos命令环境。输入javac打印出一系列用法提示和输入mvn -v打印出Maven版本代表环境配置成功。

配置文件修改:

因为在国内使用Maven默认的远程仓库地址下载的比较慢,所以一般都会换成国内的淘宝镜像。
找到maven安装路径下的conf文件夹里的settings.xml文件
打开,修改镜像地址为

  
    
      alimaven
      aliyun maven
      http://maven.aliyun.com/nexus/content/groups/public/
      central        
    
  

同时一并替换了本地仓库地址,因为默认仓库地址在C盘,时间久了包会越来越多,占用C盘空间

 你的非C盘地址

使用Idea创建Maven工程

在Idea中新建工程,选择Maven工程,创建web-app的archetype


Maven工程创建

选择好了后,下一步。根据下图中提示配置项目信息。

项目信息填写

下一步

Maven配置

点击Finish。首次创建Maven会从远程仓库开始下jar包,需要等待一会儿。
maven自动执行完成后,你的项目根目录中就会有pom.xml这个文件,可以把这个文件理解为前端项目中的package.json文件,主要用于映射远程仓库的包,配置完后,运行maven命令会自动帮你下包(此处注意Idea右下角提示,选择自动运行导包),配置如下(主要是引入Junit测试和http访问,以及一些maven插件)




  4.0.0

  com.hzmeurasia
  WxAuth
  1.0-SNAPSHOT
  war

  WxAuth Maven Webapp
  
  http://www.example.com

  
    UTF-8
    1.7
    1.7
  

  
    
      junit
      junit
      4.11
      test
    
    
      org.apache.httpcomponents
      httpclient
      4.5.5
    

    
      com.hynnet
      json-lib
      2.4
    
  

  
    WxAuth
    
      
        
          maven-clean-plugin
          3.1.0
        
        
        
          maven-resources-plugin
          3.0.2
        
        
          maven-compiler-plugin
          3.8.0
        
        
          maven-surefire-plugin
          2.22.1
        
        
          maven-war-plugin
          3.2.2
        
        
          maven-install-plugin
          2.5.2
        
        
          maven-deploy-plugin
          2.8.2
        
      
    
  

配置Tomcat服务器

下载:

进入官网,选择Tomcat 8.5.50版本进行下载。https://tomcat.apache.org/download-80.cgi

Tomcat 8.5.50下载

注:最好下载Tomcat7或8的版本,版本太新出错不好调试

Tomcat的手动启动和关闭

下载完成后,直接解压。找到bin目录下的startup.batshutdown.bat,分别用于手动打开和关闭Tomcat服务。
双击startup.bat,打开浏览器地址栏输入:http://localhost:8080/,能显示出Tomcat默认网页就表示成功

Tomcat环境变量配置

安装完成后,右击我的电脑,点击属性,选择高级系统设置,点击环境变量

配置环境变量

系统变量中添加
变量名:CATALINA_BASE
变量值:D:\Tomcat\apache-tomcat-8.5.50 (Tomcat安装目录)
变量名:CATALINA_HOME
变量值:同Tomcat安装目录

系统变量

修改ClassPathPath变量
ClassPath变量值加入:%CATALINA_HOME%\lib\servlet-api.jar;
Path变量加入:%CATALINA_HOME%\bin;%CATALINA_HOME%\lib

ClassPath

Path

点击确定,Tomcat就配置好了。

验证:

点击"开始"->"运行",键入"cmd"(或快捷键win+R);键入命令:startup,出现以下信息,说明环境变量配置成功

Tomcat启动

关闭窗口,即可关闭Tomcat服务

Idea配置Tomcat

打开刚才创建的Maven项目,点击Run---Edit Configurations...


Idea配置Tomcat

点击左侧“+”号,找到Tomcat Server---Local(若是没有找到Tomcat Server 可以点击最后一行 34 items more)

Idea配置Tomcat

Idea配置Tomcat

在Tomcat Server -> Unnamed -> Server -> Application server项目下,点击 Configuration ,找到本地 Tomcat 服务器,再点击 OK按钮。


Idea配置Tomcat

这里尤其要注意一下端口号,建议先填80端口。如果要修改端口号,之后在微信的回调域名的必须要加上端口号,因为微信授权默认回调域名端口号为80端口

引入servlet的api

点击项目右上角打开工程结构的按钮


Project Structure

选择Library,如图所示添加

引入servlet-api

选择Tomcat安装路径下的lib中的servlet-api.jar
servlet-api

之后一路点Ok,完成。

配置内网穿透

内网穿透,即NAT穿透,网络连接时术语,计算机是局域网内时,外网与内网的计算机节点需要连接通信,有时就会出现不支持内网穿透。就是说映射端口,能让外网的电脑找到处于内网的电脑

本文中采用的是NATAPP提供的内网穿透服务,作为案例。
NATAPP官网: https://natapp.cn/
NATAPP1分钟快速新手图文教程:https://natapp.cn/article/natapp_newbie
参考以上教程,从官网下载客户端,得到natapp.exe运行程序
windows ,点击开始->运行->命令行提示符 后进入 natapp.exe的目录
运行 natapp -authtoken=你的密钥
运行成功,都可以得到如下界面:

启动内网穿透服务

做完了这些配置信息后,就可以开始正式写代码了。

配置工具类

在src/main/java/com/wx/auth/util下新建AuthUtil.java文件,写网络请求访问工具方法,例:

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 微信授权网络请求工具类
 * @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在微信公众号测试号网页获取


APPID和APPSECRET

微信校验第一步:用户同意授权,获取code

微信网页授权开发文档
首先公众号需具备网页H5授权权限,我们在文章开头申请的微信公众号测试号已具备H5授权权限。
之后,要引导用户跳转到微信指定的网页并配置回调地址。
在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 登录验证
 * @date 2019/12/29 21:05
 **/
@WebServlet("/wxLogin")
public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 回调地址
        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);
    }
}

此处注意参数顺序,因为微信的地址是对传参顺序正则强校验。
回调地址的域名是我们之前开启NATAPP服务得到的公网地址

微信校验第二步:通过code换取网页授权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 授权回调
 * @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");
}

微信校验第三步:刷新access_token(如果需要)

这里我们不需要刷新token,如果需要大家可看官网文档。

微信校验第四步:拉取用户信息(需scope为 snsapi_userinfo)

对第二步的CallBackServelet.java代码进行扩充,用获取到的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 授权回调
 * @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:直接使用微信用户信息直接登录,无需注册和绑定
        req.setAttribute("info", userInfo);
        req.getRequestDispatcher("/loginSuccess.jsp").forward(req, resp);
}

配置入口和成功页面

在src/main/webapp下新建index.jsp(首次进入,网页默认访问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" %>




    微信授权


微信公众号授权


在src/main/webapp下新建loginSuccess.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" %>
<%--JSP和Servlet版本导致el功能默认关闭,加入<%@page isELIgnored="false"%>标签手动开启el功能--%>
<%@ page isELIgnored="false"%>




    登录结果


    
登录成功
用户昵称: ${info.nickname}
用户头像:

最后需要把NATAPP生成的域名在微信公众号测试号设置为安全域名

修改JS接口安全域名

在体验接口权限表里,找到网页服务项里的网页账号项,点击修改
体验接口权限表

至此,可以启动Tomcat服务了。在Idea工具中可以快捷启动
Tomcat启动

访问localhost/WxAuth/出现如下页面表示本地项目成功启动。
微信公众号授权

访问项目的线上地址http://你申请到的临时域名/WxAuth/,如果出现同样的页面表示内网穿透成功,本地地址已经成功映射到线上。
在微信中点击该链接(如果在非微信浏览器点击,授权时会提示“请在微信访问该网页”)
首次点击会出现是否授权页面。
是否授权

同意之后,获取到用户信息
用户信息

你可能感兴趣的:(Idea使用Maven和Tomcat实现微信授权)