>  기사  >  백엔드 개발  >  네이티브 PHP는 사용자 정보를 얻기 위해 Alipay 앱에 제3자 로그인을 구현합니다.

네이티브 PHP는 사용자 정보를 얻기 위해 Alipay 앱에 제3자 로그인을 구현합니다.

藏色散人
藏色散人앞으로
2019-08-22 14:03:304225검색

Background

앱 프로젝트에는 제3자 WeChat 및 Alipay 로그인이 필요합니다. WeChat은 사용자 정보를 얻기 위해 앱 측에서 직접 인증을 완료할 수 있지만 Alipay는 백엔드 획득이 필요합니다.

Process

1. 먼저 앱이 Alipay SDK를 호출하는 데 필요한 infoStr을 가져옵니다

2. 앱은 infoStr

3을 통해 사용자 인증 코드를 가져옵니다.

4. 서버는 토큰

code

을 통해 사용자 정보를 얻습니다. 이에 앞서 Alipay 인터페이스 도킹 프로세스에 대한 이해가 필요합니다.

1. RSA2 방법 생성: Get sign:

/**
 * enRSA2 RSA加密
 * 
 * @param String $data
 * @return String
 */
private function enRSA2($data)
{
    $str = chunk_split(trim($this->private_key), 64, "\n");
    $key = "-----BEGIN RSA PRIVATE KEY-----\n$str-----END RSA PRIVATE KEY-----\n";
    // $key = file_get_contents(storage_path('rsa_private_key.pem')); 为文件时这样引入
    $signature = '';
    $signature = openssl_sign($data, $signature, $key, OPENSSL_ALGO_SHA256)?base64_encode($signature):NULL;
    return $signature;
}

2 Alipay 서명 문자열 요구 사항을 충족하는지 확인하기 위한 Get 매개변수 접합 방법 생성:

/**
 * myHttpBuildQuery
 * 之所以不用 自带函数 `http_build_query` 
 * 是因为格式化的时间带有  ‘:’  会被转换成十六进制 utf-8 码
 * 
 * @param Array
 * @return String
 */
private function myHttpBuildQuery($dataArr)
{
    ksort($dataArr);
    $signStr = '';
    foreach ($dataArr as $key => $val) {
        if (empty($signStr)) {
            $signStr = $key.'='.$val;
        } else {
            $signStr .= '&'.$key.'='.$val;
        }
    }
    return $signStr;  
}

3 앱에 필요한 infoStr 제공:

/**
 * InfoStr APP登录需要的的infostr
 * 
 * @return String
 */
public function infoStr()
{
    $infoStr = http_build_query([
        'apiname' => 'com.alipay.account.auth',
        'method' => 'alipay.open.auth.sdk.code.get',
        'app_id' => $this->app_id,
        'app_name' => 'mc',
        'biz_type' => 'openservice',
        'pid' => $this->pid,
        'product_id' => 'APP_FAST_LOGIN',
        'scope' => 'kuaijie',
        'target_id' => mt_rand(999, 99999), //商户标识该次用户授权请求的ID,该值在商户端应保持唯一
        'auth_type' => 'AUTHACCOUNT', // AUTHACCOUNT代表授权;LOGIN代表登录
        'sign_type' => 'RSA2',
    ]);
    $infoStr .= '&sign='.$this->enRSA2($infoStr);
    return $infoStr;
}

4, 사용자 정보 가져오기:

 /**
     * AlipayToken 获得用户 请求token, 通过它获得 用户信息
     * 
     * 需要按照支付宝加签流程来。
     */
    public function userInfo($app_auth_token)
    {
        $infoArr = [
            'method' => 'alipay.system.oauth.token',
            'app_id' => $this->app_id,
            'charset' => 'utf-8',
            'sign_type' => 'RSA2',
            'timestamp' => date('Y-m-d H:i:s'),
            'version' => '1.0',
            'code' => $app_auth_token,
            'grant_type' => 'authorization_code',
        ];
        $signStr = $this->myHttpBuildQuery($infoArr);
        $sign = urlencode($this->enRSA2($signStr));
        $qureStr = $signStr.'&sign='.$sign;
        $res = new Client();
        $body = $res->get('https://openapi.alipay.com/gateway.do?'.$qureStr)->getBody()->getContents();
        $body = json_decode($body);
        if (!isset($body->alipay_system_oauth_token_response->access_token)) {
            return '接口异常';
        } else {
            $autho_token = $body->alipay_system_oauth_token_response->access_token;
            $userinfo = $this->aliPayUserInfo($autho_token);
            return $userinfo; // 或则 返回 json_encode($userinfo) 根据实际需求来 
        }
    }
    /**
     * AliPayUserInfo 通过 token 获取用户信息
     */
    private function aliPayUserInfo($autho_token)
    {
        $infoArr = [
            'method' => 'alipay.user.info.share',
            'app_id' => $this->app_id,
            'charset' => 'utf-8',
            'sign_type' => 'RSA2',
            'timestamp' => date('Y-m-d H:i:s'),
            'version' => '1.0',
            'auth_token' => $autho_token,
        ];
        $signStr = $this->myHttpBuildQuery($infoArr);
        $sign = urlencode($this->enRSA2($signStr));
        $qureStr = $signStr.'&sign='.$sign;
        $res = new Client();
        $body = $res->get('https://openapi.alipay.com/gateway.do?'.$qureStr)->getBody()->getContents();
        $body = json_decode($body);
        if (!isset($body->alipay_user_info_share_response)) {
            return '接口异常';
        }
        $body = $body->alipay_user_info_share_response;
        return $body;
    }

코드 개요

 'com.alipay.account.auth',
            'method' => 'alipay.open.auth.sdk.code.get',
            'app_id' => $this->app_id,
            'app_name' => 'mc',
            'biz_type' => 'openservice',
            'pid' => $this->pid,
            'product_id' => 'APP_FAST_LOGIN',
            'scope' => 'kuaijie',
            'target_id' => mt_rand(999, 99999), //商户标识该次用户授权请求的ID,该值在商户端应保持唯一
            'auth_type' => 'AUTHACCOUNT', // AUTHACCOUNT代表授权;LOGIN代表登录
            'sign_type' => 'RSA2',
        ]);
        $infoStr .= '&sign='.$this->enRSA2($infoStr);
        return $infoStr;
    }
     /**
     * AlipayToken 获得用户 请求token, 通过它获得 用户信息
     * 
     * 需要按照支付宝加签流程来。
     */
    public function userInfo($app_auth_token)
    {
        $infoArr = [
            'method' => 'alipay.system.oauth.token',
            'app_id' => $this->app_id,
            'charset' => 'utf-8',
            'sign_type' => 'RSA2',
            'timestamp' => date('Y-m-d H:i:s'),
            'version' => '1.0',
            'code' => $app_auth_token,
            'grant_type' => 'authorization_code',
        ];
        $signStr = $this->myHttpBuildQuery($infoArr);
        $sign = urlencode($this->enRSA2($signStr));
        $qureStr = $signStr.'&sign='.$sign;
        $res = new Client();
        $body = $res->get('https://openapi.alipay.com/gateway.do?'.$qureStr)->getBody()->getContents();
        $body = json_decode($body);
        if (!isset($body->alipay_system_oauth_token_response->access_token)) {
            return '接口异常';
        } else {
            $autho_token = $body->alipay_system_oauth_token_response->access_token;
            $userinfo = $this->aliPayUserInfo($autho_token);
            return $userinfo; // 或则 返回 json_encode($userinfo) 根据实际需求来 
        }
    }
    /**
     * AliPayUserInfo 通过 token 获取用户信息
     */
    private function aliPayUserInfo($autho_token)
    {
        $infoArr = [
            'method' => 'alipay.user.info.share',
            'app_id' => $this->app_id,
            'charset' => 'utf-8',
            'sign_type' => 'RSA2',
            'timestamp' => date('Y-m-d H:i:s'),
            'version' => '1.0',
            'auth_token' => $autho_token,
        ];
        $signStr = $this->myHttpBuildQuery($infoArr);
        $sign = urlencode($this->enRSA2($signStr));
        $qureStr = $signStr.'&sign='.$sign;
        $res = new Client();
        $body = $res->get('https://openapi.alipay.com/gateway.do?'.$qureStr)->getBody()->getContents();
        $body = json_decode($body);
        if (!isset($body->alipay_user_info_share_response)) {
            return '接口异常';
        }
        $body = $body->alipay_user_info_share_response;
        return $body;
    }
    /**
     * enRSA2 RSA加密
     * 
     * @param String $data
     * @return String
     */
    private function enRSA2($data)
    {
        $str = chunk_split(trim($this->private_key), 64, "\n");
        $key = "-----BEGIN RSA PRIVATE KEY-----\n$str-----END RSA PRIVATE KEY-----\n";
        // $key = file_get_contents(storage_path('rsa_private_key.pem')); 为文件时这样引入
        $signature = '';
        $signature = openssl_sign($data, $signature, $key, OPENSSL_ALGO_SHA256)?base64_encode($signature):NULL;
        return $signature;
    }
    /**
     * myHttpBuildQuery 返回一个 http Get 传参数组
     * 之所以不用 自带函数 http_build_query 时间带 ‘:’ 会被转换
     * 
     * @param Array
     * @return String
     */
    private function myHttpBuildQuery($dataArr)
    {
        ksort($dataArr);
        $signStr = '';
        foreach ($dataArr as $key => $val) {
            if (empty($signStr)) {
                $signStr = $key.'='.$val;
            } else {
                $signStr .= '&'.$key.'='.$val;
            }
        }
        return $signStr;  
    }
}

Others

1 참고: 이 코드는 주로 이러한 요구가 있는 개발자에게 참조를 제공하기 위해 원래 프로젝트에서 추출되었습니다. 직접 사용할 수 있는지 테스트를 거쳤으므로 직접 테스트해 보세요.

2. Alipay php_SDK를 사용하지 않는 이유는 수요가 제한되어 있기 때문입니다. 필요하지 않은 사용자 정보만 가져옵니다.

3. 모두가 서로 배울 수 있도록 코드에서 불합리한 부분을 지적해주세요.

위 내용은 네이티브 PHP는 사용자 정보를 얻기 위해 Alipay 앱에 제3자 로그인을 구현합니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 learnku.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제