第三方登录(三)支付宝登录

开发接入,创建应用

登录开发者中心,创建网页&移动应用,然后填写相关信息,提交。

进入到应用的概览面板,在功能列表栏出点击添加功能按钮,然后搜索并选择“获取会员信息”这一项,如下图:

由于有些功能是需要签约的,所以将用不到的功能删除。

创建RSA密钥

为应用生成RSA密钥,RSA密钥包含应用私钥(APP_PRIVATE_KEY)、应用公钥(APP_PUBLIC_KEY),然后可以得到支付宝公钥(ALIPAY_PUBLIC_KEY)。

继续之前的页面,再往下到开发设置,设置接口加签方式,加签模式选择公钥。下载支付宝密钥生成器并点击“生成密钥”按钮。各项选择如下图所示:

点击链接 “上传公钥”,把公钥上传至支付宝开放平台,并设置AES密钥和授权回调地址,如下图:

生成的私钥公钥同样以文本文件形式保存在工具存放目录的 “RSA密钥”文件夹下,点击按钮 “打开密钥文件路径”即可打开“RSA密钥”文件夹,看到应用公钥和应用私钥两个文件。

再回到开发设置页面,把密钥生成器生成的应用公钥上传至下方输入框,如下图:

点击保存设置,然后会弹出来刚才上传的应用公钥和支付宝公钥。至此,接口加密方式及应用设置完毕。编码阶段,实际使用到的是支付宝公钥应用私钥

授权思路

为了使后面思路更加清晰,我们先说一下授权登录的思路,其实和QQ以及微博相似。用户点击授权登录按钮,触发授权,用户同意授权后,支付宝携带auth_code跳转至回调地址里面,然后通过auth_code获取获取access_token及user_id。最后通过access_token拿到用户的信息。

编码部分

先下载官方SDK,下载地址:

https://docs.open.alipay.com/54/103419/

我这里使用ThinkPHP3.2(其他框架比葫芦画瓢),将下载下来的SDK文件夹命名为Alipay放置到ThinkPHP的Vendor目录下。

前台用户点击支付宝登录,链接到Api模块下的Alilogin控制器ali_login方法。

下面放代码:

Alilogin控制器:

<?php
namespace Api\Controller;

use Vendor\Page;
use Think\Controller;

class AliloginController extends Controller
{
    const GET_AUTH_CODE_URL = "https://openauth.alipay.com/oauth2/publicAppAuthorize.htm";

    public function ali_login(){
        //获取USER AGENT
         $is_mobile = isMobile();
        //分析数据
        //-------生成唯一随机串防CSRF攻击
        $_SESSION['state'] = md5(uniqid(rand(), TRUE));
        $keysArr = array(
            "app_id" =>  C('ALI_APPID'),
            "redirect_uri" => C('ALI_CALLBACK'),
            "state" => $_SESSION['state'],
            "scope" => C('ALI_SCOPE')
        );
        if($is_mobile){
            //手机端调用用这个
            $fi_url = self::GET_AUTH_CODE_URL.'?'.http_build_query($keysArr);
            $login_url = 'alipays://platformapi/startapp?appId=20000067&url='.urlencode($fi_url);
        }else{
            $login_url = self::GET_AUTH_CODE_URL.'?'.http_build_query($keysArr);
        }
        header("Location:$login_url");
    }

    public  function redirect_url()
    {
        vendor('Alipay.aop.AopClient');
        $code = $_GET['auth_code'];
        $aop = new \AopClient();
        $aop->appId = C('ALI_APPID');
        $aop->rsaPrivateKey = C('RSA_PRIVATE_KEY');
        $aop->alipayrsaPublicKey=C('ALIPAY_RSA_PBULIC_KEY');
        $aop->gatewayUrl = 'https://openapi.alipay.com/gateway.do';
        $aop->apiVersion = '1.0';
        $aop->postCharset='utf-8';
        $aop->format='json';
        $aop->signType = 'RSA2';
        //第二步使用auth_code换取接口access_token及用户user_id
        vendor('Alipay.aop.request.AlipaySystemOauthTokenRequest');
        $request = new \AlipaySystemOauthTokenRequest();
        //请求的必传信息
        $request->setGrantType("authorization_code");
        $request->setCode($code);
        $result = $aop->execute($request);
        $responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response";
        $access_token = $result->$responseNode->access_token;
//        vendor('Alipay.aop.request.AlipayUserUserinfoShareRequest');
//        $request_a = new \AlipayUserUserinfoShareRequest();    //配置中的scope需要为auth_userinfo,只能获取用户的uid
        vendor('Alipay.aop.request.AlipayUserInfoShareRequest');
        $request_a = new \AlipayUserInfoShareRequest();    //配置中的scope需要为auth_user
        $result_a = $aop->execute ($request_a,$access_token);
        $responseNode_a = str_replace(".", "_", $request_a->getApiMethodName()) . "_response";
        $user_id = $result_a->$responseNode_a->user_id; //用户唯一uid
        //查看用户是否已注册
        $exist = M('user') -> where(['ali_uid' => $user_id]) -> getField('id');
        if($exist){
            session('uid',$exist);
            $this -> redirect('Home/Index/index');
        }else{
            $data['ali_uid'] = $user_id;
            if($result_a->$responseNode_a->avatar){
                $data['avatar'] = $result_a->$responseNode_a->avatar;   //用户头像
            }
            if($result_a->$responseNode_a->nick_name){
                $data['nickname'] = $result_a->$responseNode_a->nick_name;   //用户昵称
            }
            if($result_a->$responseNode_a->province){
                $data['province'] = $result_a->$responseNode_a->province;
            }
            if($result_a->$responseNode_a->city){
                $data['city'] = $result_a->$responseNode_a->city;
            }
            $res = M('user') -> add($data);
            if($res){
                session('uid',$res);
                $this -> redirect('Home/Index/index');
            }
        }
    }
}

config.php

<?php
return array(//'配置项'=>'配置值'
    //支付宝登录配置
    'ALI_APPID' => '应用APPID',
    'ALI_CALLBACK' => 'https://example.acier.cn/index.php/Api/Alilogin/redirect_url',
    'ALI_SCOPE' => 'auth_user,auth_base',
    //支付宝公钥
    'ALIPAY_RSA_PBULIC_KEY' => '注意,是支付宝公钥',
    //应用私钥
    'RSA_PRIVATE_KEY' => '注意,是应用私钥'
);

结尾

配置文件中ALI_SCOPE项,auth_base:以auth_base为scope发起的网页授权,是用来获取进入页面的用户的user_id的,并且是静默授权并自动跳转到回调页的。用户感知的就是直接进入了回调页(通常是业务页面)。
auth_user:以auth_user为scope发起的网页授权,是用来获取用户的基本信息的(比如头像、昵称等)。但这种授权需要用户手动同意,用户同意后,就可在授权后获取到该用户的基本信息。若想获取用户信息,scope的值中需要有该值存在,如'ALI_SCOPE' => 'auth_user,auth_base'

发表评论

发表回复

沙发空缺中,还不快抢~