微信、QQOAuth 2.0前后端登录代码

由于不同的第三方平台的授权方式不同,包括授权的端点、授权的参数等等,因此,下面我们提供了分别用于QQ、微信、钉钉OAuth 2.0的前端和后端代码。

首先是QQ OAuth 2.0的前端代码,它使用QQ提供的connect.qq.com授权端点进行授权,并处理授权的回调:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>QQ OAuth 2.0</title>
</head>
<body>

<h1>QQ OAuth 2.0</h1>

<script src="https://open.mobile.qq.com/sdk/qqapi.js?_bid=152"></script>

<script>
    var appId = 'YOUR_APP_ID_HERE',
        redirectUri = encodeURIComponent('http://localhost:8080/oauth/callback/qq'),
        scope = 'get_user_info';

    qq.login(function(res) {
        if (res.errMsg == 'login:ok') {
            var access_token = res.access_token,
                expires_in = res.expires_in,
                openid = res.openid;

            // Send OAuth login data to server-side
            var xhr = new XMLHttpRequest();
            xhr.open('POST', 'http://localhost:8080/oauth2/callback', true);
            xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
            xhr.onreadystatechange = function() {
                if (this.readyState == 4 && this.status == 200) {
                    // Handle successful login
                    window.location.href = "/";
                }
            };
            xhr.send('provider=qq&access_token=' + access_token + '&expires_in=' + expires_in + '&openid=' + openid);
        }
    }, {
        clientId: appId,
        scope: scope,
        redirectURI: redirectUri
    });
</script>

</body>
</html>

接下来是QQ OAuth 2.0的后端代码,它将处理来自QQ的OAuth回调,并从回调中提取访问令牌等数据:

import java.io.IOException;
import java.util.Properties;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONException;
import org.json.JSONObject;

public class QQOAuth2CallbackServlet extends HttpServlet {

    private static final String CALLBACK_PATH = "/oauth/callback/qq";
    private static final String AUTHORIZATION_ENDPOINT = "https://graph.qq.com/oauth2.0/authorize";
    private static final String TOKEN_ENDPOINT = "https://graph.qq.com/oauth2.0/token";
    private static final String USERINFO_ENDPOINT = "https://graph.qq.com/user/get_user_info";

    private static final String APP_ID = "YOUR_APP_ID_HERE";
    private static final String APP_KEY = "YOUR_APP_KEY_HERE";
    private static final String REDIRECT_URI = "http://localhost:8080/oauth/callback/qq";

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String code = req.getParameter("code");
        String state = req.getParameter("state");

        String access_token = "";
        String openid = "";

        String token_url = TOKEN_ENDPOINT + "?grant_type=authorization_code&client_id="
                + APP_ID + "&client_secret=" + APP_KEY + "&code=" + code + "&redirect_uri="
                + REDIRECT_URI;

        CloseableHttpClient httpclient = HttpClientBuilder.create().build();
        HttpPost httpPost = new HttpPost(token_url);

        HttpResponse response = httpclient.execute(httpPost);
        HttpEntity entity = response.getEntity();

        if (entity != null) {
            String content = EntityUtils.toString(entity);
            String[] items = content.split("&");
            for (String item : items) {
                if (item.startsWith("access_token=")) {
                    access_token = item.substring(13);
                } else if (item.startsWith("expires_in=")) {
                    // 这个令牌将在多少秒后过期
                    int expiresIn = Integer.parseInt(item.substring(11));
                } else if (item.startsWith("refresh_token=")) {
                    // 如果支持刷新令牌,那么这里将包含一个用于获取新访问令牌的令牌
                    String refresh_token = item.substring(14);
                }
            }
        }

        // 使用令牌请求QQ的OpenID
        CloseableHttpClient httpclient2 = HttpClientBuilder.create().build();
        HttpPost httpPost2 = new HttpPost(
                "https://graph.qq.com/oauth2.0/me?access_token=" + access_token);

        HttpResponse response2 = httpclient2.execute(httpPost2);
        HttpEntity entity2 = response2.getEntity();

        if (entity2 != null) {
            String content = EntityUtils.toString(entity2);
            content = content.replace("callback( ", "");
            content = content.replace(" );", "");

            JSONObject json = new JSONObject(content);
            openid = json.getString("openid");
        }

        // 使用QQ的 openid 获取用户信息
        CloseableHttpClient httpclient3 = HttpClientBuilder.create().build();
        HttpPost httpPost3 = new HttpPost(USERINFO_ENDPOINT + "?access_token=" + access_token
                + "&oauth_consumer_key=" + APP_ID + "&openid=" + openid);

        HttpResponse response3 = httpclient3.execute(httpPost3);
        HttpEntity entity3 = response3.getEntity();

        if (entity3 != null) {
            String content = EntityUtils.toString(entity3);
            JSONObject json = new JSONObject(content);

            String nickname = json.getString("nickname");
            String gender = json.getString("gender");
            String avatar = json.getString("figureurl_qq_2");
            int province = json.getInt("province");
            int city = json.getInt("city");

            // do something with user info
        }

        // redirect user to homepage after successful authentication
        resp.sendRedirect("/");
    }
}

下面是微信OAuth 2.0的前端代码,它使用微信提供的open.weixin.qq.com授权端点进行授权,并处理授权的回调:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>WeChat OAuth 2.0</title>
</head>
<body>

<h1>WeChat OAuth 2.0</h1>

<script src="//res.wx.qq.com/connect/sdk/jsfile/sdk/versions/version1.6.0/mmversion.js"></script>

<script>
    var appId = 'YOUR_APP_ID_HERE',
        redirectUri = encodeURIComponent('http://localhost:8080/oauth/callback/weixin'),
        scope = 'snsapi_login';

    document.addEventListener("WeixinJSBridgeReady", function () {
        WeixinJSBridge.invoke('getLoginStatus', {}, function (res) {
            if (res.err_msg == "login:ok") {
                var code = res.code;

                // Send OAuth login data to server-side
                var xhr = new XMLHttpRequest();
                xhr.open('POST', 'http://localhost:8080/oauth2/callback', true);
                xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
                xhr.onreadystatechange = function() {
                    if (this.readyState == 4 && this.status == 200) {
                        // Handle successful login
                        window.location.href = "/";
                    }
                };
                xhr.send('provider=weixin&code=' + code);
            } else {
                WeixinJSBridge.invoke('authorize', {
                    scope: scope,
                    state: 'wx_login'
                }, function(res) {});
            }
        });
    }, false);
</script>

</body

猜你喜欢

转载自blog.csdn.net/a913222/article/details/130144993