第三方登录

Zerone 提供多个服务,帮您快速接入第三方登录。

提示

当您获取完用户后,可以使用身份验证插件完成登录。

警告

不要公开暴露示例中的密钥(secret)。我们在这里这样做是为了向您明确代码在做什么,但在生产环境中,您必须使用适当的措施来保护此密钥, 例如秘钥库、环境变量或配置服务。

微信

安装Zerone 提供的微信登录服务包,其中包括 微信网页授权、微信小程序授权。

yarn add @zeronejs/wechat-login
1
npm install @zeronejs/wechat-login
1

微信网页授权

在你需要微信网页授权的模块(module)提供WechatLoginOauth2Service服务。

import { WechatLoginOauth2Service } from '@zeronejs/wechat-login';

@Module({
    ...
    providers: [..., WechatLoginOauth2Service],
})
export class userModule {}
1
2
3
4
5
6
7
公众号配置

请参阅微信网页授权官网文档在新窗口打开提供的配置说明。

功能

WechatLoginOauth2Service提供多个方法,你只需传递参数,Zerone帮你对接微信。

方法名说明
getCode第一步:用户同意授权,获取code在新窗口打开
getAccessToken第二步:通过code换取网页授权access_token在新窗口打开
refreshAccessToken第三步:刷新access_token(如果需要)在新窗口打开
getUserInfo第四步:拉取用户信息(需scope为 snsapi_userinfo)在新窗口打开
checkAccessToken附:检验授权凭证(access_token)是否有效在新窗口打开
示例
import { WechatLoginOauth2Service } from '@zeronejs/wechat-login';
import { Request, Response } from 'express';
...
@Controller()
class UserController { // 你的控制器
    constructor(
        // 注入服务
        private readonly wechatLoginOauth2Service: WechatLoginOauth2Service,
    ) {}
    
    @Get('/webLogin') // 自定义路由
    async webLogin(@Res() res: Response) {
        // 第一步
        const url = this.wechatLoginOauth2Service.getCode({
            appid: 'wx1d7fa6b14a9xxxxx', // 公众号appid
            redirect_uri: encodeURIComponent('https://www.example.com/webLogin/redirectUri'), // 授权后重定向的回调链接地址, 请填写你自己的
            scope: 'snsapi_userinfo', // 应用授权作用域 ,根据自己需求提供
        });
        return res.redirect(url);
    }
    // 填写的回调链接地址
    @Get('/webLogin/redirectUri')
    async redirectUri(@Req() req: Request) {
        // 第二步
        const actoken = await this.wechatLoginOauth2Service.getAccessToken({
            appid: 'wx1d7fa6b14a9xxxxx',// 公众号appid
            secret: 'xxxxxxxxxxxxxxx',// 公众号的appsecret
            code: req.query.code as string,
        });
        // 第四步
        const userInfo = await this.wechatLoginOauth2Service.getUserInfo({
            access_token: actoken.data.access_token,
            openid: actoken.data.openid,
            lang: 'zh_CN',
        });
        // ... 数据库、登录等等 
     
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

微信小程序登录

在你需要微信小程序登录的模块(module)提供WechatLoginMiniProgramService服务。

import { WechatLoginMiniProgramService } from '@zeronejs/wechat-login';

@Module({
    ...
    providers: [..., WechatLoginMiniProgramService],
})
export class userModule {}
1
2
3
4
5
6
7
登录时序

登录流程时序详见 小程序登录在新窗口打开

功能

WechatLoginMiniProgramService提供多个方法,你只需传递参数,Zerone帮你对接微信。

方法名说明
code2sessioncode换取session_key、openid、unionid在新窗口打开
getUserProfile完整用户信息的解密在新窗口打开
wxLoginjscode2session、getUserProfile 的合集
示例
  1. 小程序端调用 wx.login()在新窗口打开 获取 临时登录凭证code ,并回传到开发者服务器。

  2. 服务端通过code 换取session_key, openid和unionid

import { WechatLoginMiniProgramService } from '@zeronejs/wechat-login';
...
@Controller()
class UserController { // 你的控制器
    constructor(
        // 注入服务
        private readonly wechatLoginMiniProgramService: WechatLoginMiniProgramService,
    ) {}
    @Post('code2session') // 你的自定义路由
    async code2session(@Body() body: any) {
        const { code } = body;
        const { session_key, openid, unionid } = await this.wechatLoginMiniProgramService.code2session({
            appId: 'wxbcf4c453d6exxxxx',
            secret: 'xxxxxxxxxxxxxxxxxxxx',
            code,
        });
        // ... 数据库、登录等等
    }
    
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
  1. 小程序端调用 wx.getUserProfile()在新窗口打开 获取完整用户信息的加密数据encryptedData和加密算法的初始向量 iv

  2. 服务端解密数据

    ...
    @Post('getUserProfile') // 你的自定义路由
    async getUserProfile(@Body() body: any) {
        const { encryptedData, iv } = body;
        const data = this.wechatLoginMiniProgramService.getUserProfile({
            appId: 'wxbcf4c453d6exxxxx',
            encryptedData,
            iv,
            session_key, // 由第二步获取
        });
        // ... 数据库、登录等等
    }
    
1
2
3
4
5
6
7
8
9
10
11
12
13
一步完成?
    ...
    const { code, encryptedData, iv } = body;
    const user = await this.wechatLoginMiniProgramService.wxLogin({
        appId: 'wxbcf4c453d6exxxxx',
        secret: 'xxxxxxxxxxxxxxxxxxxx',
        code,
        encryptedData,
        iv,
    });
    // ... 数据库、登录等等
1
2
3
4
5
6
7
8
9
10

网站应用扫码登录

网站应用微信登录开发指南在新窗口打开

服务器Token验证

详见微信公众号接入指南在新窗口打开

import { wechatVerifyServerToken } from "@zeronejs/wechat-login";
...
    @Get('/wx') // 你填写的服务器路由
    async wxServer(@Query() query: any) {
        const { signature, timestamp, nonce, echostr } = query;
        const token = '你填写的Token';
        return wechatVerifyServerToken({
            signature,
            timestamp,
            nonce,
            echostr,
            token
        })
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14

支付宝

本章将带您实现小程序登录PC网页内登录

支付宝小程序登录

参考 支付宝小程序获取会员基础信息在新窗口打开

依赖

提示

示例由uni-app在新窗口打开构建。你也可以使用其他或原生,用它只是给你提供思路。

第一步:添加授权按钮

<button open-type="getAuthorize" @getAuthorize="getUser" 
    onGetAuthorize="getUser" onError="onAuthError" scope='userInfo'>
	会员基础信息授权
</button>
1
2
3
4

第二步:授权登录和获取用户信息

uni.login({
    success: (loginRes) => {
        // 获取用户信息
        uni.getUserInfo({
            provider: "alipay",
            success: (infoRes) => {
                const userInfo = JSON.parse(infoRes.response).response // 以下方的报文格式解析两层 response
                // 数据发送至服务器端
                uni.request({
                    url: `http://example.com/somePost`,
                    data: {
                        code: loginRes.code,
                        userInfo
                    },
                    method: "POST",
                    success: (res) => {
                        // 你的代码
                    }
                });
            }
        });
    }
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

第三步:服务端获取userId

@Post('somePost')
async demo(@Body() body: any) {
    const alipay = this.alipayService.getInstance();
    const result = await alipay.exec('alipay.system.oauth.token', {
        grantType: 'authorization_code',
        code: body.code,
        // refreshToken: 'token'
    });
    console.log(result);
    // ... 数据库、登录等等
}
1
2
3
4
5
6
7
8
9
10
11

PC网页内支付宝登录

适用于移动应用、网页应用(PC 站点)等其他应用类型,参考 PC 网页内获取用户信息在新窗口打开

依赖

第一步:URL拼接

在你的Controller控制器内

    @Get('/pclogin') // 自定义路由
    async pclogin(@Res() res: Response) {
        const alipay = this.alipayService.getInstance();
        const myURL = new URL('https://openauth.alipay.com/oauth2/publicAppAuthorize.htm');
        myURL.searchParams.set('app_id', alipay.config.appId);
        myURL.searchParams.set('scope', 'auth_user');
        myURL.searchParams.set(
            'redirect_uri',
            encodeURI('https://www.example.com/pclogin/notify')// 请填写你的授权回调地址
        );
        const url = myURL.href;
        return res.redirect(url);
    }
1
2
3
4
5
6
7
8
9
10
11
12
13

第二步:授权登录和获取用户信息

    @Get('/pclogin/notify') // 自定义的授权回调页面
    async pcloginNotify(@Query() query: any) { // query携带auth_code、app_id、scope
        const alipay = this.alipayService.getInstance();
        // 第一步:换取 access_token 和 userId
        const result = await alipay.exec('alipay.system.oauth.token', {
            grantType: 'authorization_code',
            code: query.auth_code,
        });
        const { accessToken, userId, msg, code } = result;
        if (!accessToken || !msg) {
            console.log(msg, code)
            return result;
        }
        // 第二步:获取用户信息
        const user = await alipay.exec('alipay.user.info.share', {
            authToken: accessToken,
            bizContent: {},
        });
        // ... 数据库、登录等等
        console.log(user, userId);
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21