PHP 가 알 리 페 이 애플 릿 사용자 에 게 권한 을 부여 하 는 도구 클래스 를 자세히 설명 합 니 다.

배경
최근 프로젝트 는 온라인 알 리 페 이 애플 리 케 이 션 이 필요 하고 사용자 의 권한 수여 절 차 를 통 해 사용자 정보의 저장 을 완성 해 야 합 니 다.예전 에 위 챗 애플 리 케 이 션 의 개발 을 한 적 이 있 습 니 다.권한 수 여 를 실현 하 는 과정 이 간단 하 다 고 생각 했 지만 다시 실현 하 는 과정 에서 많은 구 덩이 를 만 났 기 때문에 실현 과정 을 기록 해 보 세 요.
배 운 지식
  • 알 리 페 이 개방 인터페이스의 호출 모델 과 실현 방식
  • 알 리 페 이 애플 릿 권한 수여 절차
  • RSA 암호 화 방식
  • 구유 점
    알 리 페 이 애플 릿 의 입 구 는 매우 깊이 숨겨 져 있 고 위 챗 애플 릿 만큼 직접적 이지 않다.
    알 리 페 이 애플 릿 개발 자 도 구 는 사용 하기 어렵 고 컴 파일 할 때 카드 가 많아 서 성능 에 큰 문제 가 있 습 니 다.
    매번 코드 를 제출 할 때마다 알 리 페 이 애플 릿 의 체험 코드 를 교체 해 야 하기 때문에 비교적 번 거 롭 고 localStorage 의 물건 을 어떻게 삭제 해 야 할 지 모 릅 니 다.
    사전 준비
  • 에서알 리 페 이 오픈 플랫폼개발 자 계 정 을 등록 하고 해당 하 는 인증 등 업 무 를 잘 한다
  • .
  • 작은 프로그램 을 만 들 고 관련 된 작은 프로그램 정 보 를 기록 합 니 다.알 리 페 이 공개 키,비밀 키,app 공개 키 등 을 포함 하고 알 리 페 이 정부 가 제공 하 는 해당 하 는 공개 키 생 성 도 구 를 참고 하여 공개 키 와 비밀 키 를 생 성 할 수 있 습 니 다.도구 의 다운로드 주소:전송 문
  • 알 리 페 이 애플 릿 의 서명 체 제 를 알 아 보고 상세 한 것 은https://docs.open.alipay.com/291/105974
  • 참조.
  • 알 리 페 이 애플 리 케 이 션 에서 사용자 정 보 를 얻 는 과정 을 숙지 하고 상세 한 것 은알 리 페 이 애플 릿 사용자 권한 부여 안내
  • 참조.
    권한 부여 절차
    권한 부여 순서 도

    실현 절차
  • 클 라 이언 트 는 my.getAuthCode 인 터 페 이 스 를 통 해 코드 를 가 져 와 서버 에 전송 합 니 다
  • 서버 는 코드 를 통 해 token 인 터 페 이 스 를 호출 하여 access 를 가 져 옵 니 다.token,alipay.system.oauth.token(권한 부여 액세스 토 큰 으로 바 꾸 기)
  • token 인 터 페 이 스 를 통 해 알 리 페 이 회원 조회 인터페이스 로 회원 정 보 를 얻 고 alipay.user.info.share(알 리 페 이 회원 권한 수여 정보 조회 인터페이스)
  • 가 져 온 사용자 정 보 를 데이터베이스 에 저장 합 니 다
  • AmpHelper 도구 클래스
    
    <?php
    /**
     * Created by PhpStorm.
     * User: My
     * Date: 2018/8/16
     * Time: 17:45
     */
    
    namespace App\Http\Helper;
    
    use App\Http\Helper\Sys\BusinessHelper;
    use Illuminate\Support\Facades\Log;
    
    class AmpHelper
    {
    
      const API_DOMAIN = "https://openapi.alipay.com/gateway.do?";
      const API_METHOD_GENERATE_QR = 'alipay.open.app.qrcode.create';
      const API_METHOD_AUTH_TOKEN = 'alipay.system.oauth.token';
      const API_METHOD_GET_USER_INFO = 'alipay.user.info.share';
    
      const SIGN_TYPE_RSA2 = 'RSA2';
      const VERSION = '1.0';
      const FILE_CHARSET_UTF8 = "UTF-8";
      const FILE_CHARSET_GBK = "GBK";
      const RESPONSE_OUTER_NODE_QR = 'alipay_open_app_qrcode_create_response';
      const RESPONSE_OUTER_NODE_AUTH_TOKEN = 'alipay_system_oauth_token_response';
      const RESPONSE_OUTER_NODE_USER_INFO = 'alipay_user_info_share_response';
      const RESPONSE_OUTER_NODE_ERROR_RESPONSE = 'error_response';
    
      const STATUS_CODE_SUCCESS = 10000;
      const STATUS_CODE_EXCEPT = 20000;
    
    
      /**
       *         ,  token
       * @param $code    
       *             
       */
      public static function getAmpUserInfoByAuthCode($code){
        $aliUserInfo = [];
        $tokenData = AmpHelper::getAmpToken($code);
        //  token   ,                 
        if(isset($tokenData['code'])){
          return $tokenData;
        }
        $token = formatArrValue($tokenData,'access_token');
        if($token){
          $userBusiParam = self::getAmpUserBaseParam($token);
          $url = self::buildRequestUrl($userBusiParam);
          $resonse = self::getResponse($url,self::RESPONSE_OUTER_NODE_USER_INFO);
          if($resonse['code'] == self::STATUS_CODE_SUCCESS){
            //      
            $userInfoColumn = ['user_id','avatar','province','city','nick_name','is_student_certified','user_type','user_status','is_certified','gender'];
            foreach ($userInfoColumn as $column){
              $aliUserInfo[$column] = formatArrValue($resonse,$column,'');
            }
    
          }else{
            $exceptColumns = ['code','msg','sub_code','sub_msg'];
            foreach ($exceptColumns as $column){
              $aliUserInfo[$column] = formatArrValue($resonse,$column,'');
            }
          }
        }
        return $aliUserInfo;
      }
    
    
      /**
       *      token  
       */
      public static function getAmpToken($code){
        $param = self::getAuthBaseParam($code);
        $url = self::buildRequestUrl($param);
        $response = self::getResponse($url,self::RESPONSE_OUTER_NODE_AUTH_TOKEN);
        $tokenResult = [];
        if(isset($response['code']) && $response['code'] != self::STATUS_CODE_SUCCESS){
          $exceptColumns = ['code','msg','sub_code','sub_msg'];
          foreach ($exceptColumns as $column){
            $tokenResult[$column] = formatArrValue($response,$column,'');
          }
        }else{
          $tokenResult = $response;
        }
        return $tokenResult;
      }
    
      /**
       *          
       * 433ac5ea4c044378826afe1532bcVX78
       * https://openapi.alipay.com/gateway.do?timestamp=2013-01-01 08:08:08&method=alipay.open.app.qrcode.create&app_id=2893&sign_type=RSA2&sign=ERITJKEIJKJHKKKKKKKHJEREEEEEEEEEEE&version=1.0&biz_content=
      {"url_param":"/index.html?name=ali&loc=hz", "query_param":"name=1&age=2", "describe":"     "}
      */
      public static function generateQrCode($mpPage = 'pages/index',$queryParam = [],$describe){
        $param = self::getQrcodeBaseParam($mpPage,$queryParam,$describe );
        $url = self::buildRequestUrl($param);
        $response = self::getResponse($url,self::RESPONSE_OUTER_NODE_QR);
        return $response;
      }
    
    
      /**
       *        ,                ,                       
       * key   ,                 ,               node      
       */
      public static function getResponse($url,$responseNode){
        $json = curlRequest($url);
        $response = json_decode($json,true);
        $responseContent = formatArrValue($response,$responseNode,[]);
        $errResponse = formatArrValue($response,self::RESPONSE_OUTER_NODE_ERROR_RESPONSE,[]);
        if($errResponse){
          return $errResponse;
        }
        return $responseContent;
      }
    
      /**
       *        
       */
      public static function buildQrRequestUrl($mpPage = 'pages/index',$queryParam = []){
        $paramStr = http_build_query(self::getQrBaseParam($mpPage,$queryParam));
        return self::API_DOMAIN . $paramStr;
      }
    
    
    
      /**
       *       
       */
      public static function buildRequestUrl($param){
        $paramStr = http_build_query($param);
        return self::API_DOMAIN . $paramStr;
      }
    
    
      /**
       *            
       */
      public static function getAmpUserBaseParam($token){
        $busiParam = [
          'auth_token' => $token,
        ];
        $param = self::buildApiBuisinessParam($busiParam,self::API_METHOD_GET_USER_INFO);
        return $param;
    
      }
    
      /**
       *          
       */
      public static function getQrcodeBaseParam($page= 'pages/index/index',$queryParam = [],$describe = ''){
        $busiParam = [
          'biz_content' => self::getQrBizContent($page,$queryParam,$describe)
        ];
        $param = self::buildApiBuisinessParam($busiParam,self::API_METHOD_GENERATE_QR);
        return $param;
    
      }
    
      /**
       *         
       */
      public static function getAuthBaseParam($code,$refreshToken = ''){
        $busiParam = [
          'grant_type' => 'authorization_code',
          'code' => $code,
          'refresh_token' => $refreshToken,
        ];
        $param = self::buildApiBuisinessParam($busiParam,self::API_METHOD_AUTH_TOKEN);
        return $param;
      }
    
    
      /**
       *       
       */
      public static function buildApiBuisinessParam($businessParam,$apiMethod){
        $pubParam = self::getApiPubParam($apiMethod);
        $businessParam = array_merge($pubParam,$businessParam);
        $signContent = self::getSignContent($businessParam);
        error_log('sign_content ===========>'.$signContent);
        $rsaHelper = new RsaHelper();
        $sign = $rsaHelper->createSign($signContent);
        error_log('sign ===========>'.$sign);
        $businessParam['sign'] = $sign;
        return $businessParam;
      }
    
    
      /**
       *     
       *
       */
      public static function getApiPubParam($apiMethod){
        $ampBaseInfo = BusinessHelper::getAmpBaseInfo();
        $param = [
          'timestamp' => date('Y-m-d H:i:s') ,
          'method' => $apiMethod,
          'app_id' => formatArrValue($ampBaseInfo,'appid',config('param.amp.appid')),
          'sign_type' =>self::SIGN_TYPE_RSA2,
          'charset' =>self::FILE_CHARSET_UTF8,
          'version' =>self::VERSION,
        ];
        return $param;
      }
    
    
      /**
       *        
       */
      public static function getSignContent($params) {
        ksort($params);
        $stringToBeSigned = "";
        $i = 0;
        foreach ($params as $k => $v) {
          if (!empty($v) && "@" != substr($v, 0, 1)) {
            if ($i == 0) {
              $stringToBeSigned .= "$k" . "=" . "$v";
            } else {
              $stringToBeSigned .= "&" . "$k" . "=" . "$v";
            }
            $i++;
          }
        }
        unset ($k, $v);
        return $stringToBeSigned;
      }
    
    
      public static function convertArrToQueryParam($param){
        $queryParam = [];
        foreach ($param as $key => $val){
          $obj = $key.'='.$val;
          array_push($queryParam,$obj);
        }
        $queryStr = implode('&',$queryParam);
        return $queryStr;
      }
    
      /**
       *        
       * @param $data
       * @param $targetCharset
       * @return string
       */
      public static function characet($data, $targetCharset) {
        if (!empty($data)) {
          $fileType = self::FILE_CHARSET_UTF8;
          if (strcasecmp($fileType, $targetCharset) != 0) {
            $data = mb_convert_encoding($data, $targetCharset, $fileType);
          }
        }
        return $data;
      }
    
      /**
       *         
       */
      public static function getQrBizContent($page, $queryParam = [],$describe = ''){
        if(is_array($queryParam)){
          $queryParam = http_build_query($queryParam);
        }
        $obj = [
          'url_param' => $page,
          'query_param' => $queryParam,
          'describe' => $describe
        ];
        $bizContent = json_encode($obj,JSON_UNESCAPED_UNICODE);
        return $bizContent;
      }
    
    }
    AmpHeler 도구 류 키 코드 분석 관련 상수
    
    //    api    
    const API_DOMAIN = "https://openapi.alipay.com/gateway.do?";
    //             
    const API_METHOD_GENERATE_QR = 'alipay.open.app.qrcode.create';
    //  token     
    const API_METHOD_AUTH_TOKEN = 'alipay.system.oauth.token';
    //           
    const API_METHOD_GET_USER_INFO = 'alipay.user.info.share';
    //        , RSA2 RSA  
    const SIGN_TYPE_RSA2 = 'RSA2';
    //   ,           
    const VERSION = '1.0';
    //UTF8  
    const FILE_CHARSET_UTF8 = "UTF-8";
    //GBK  
    const FILE_CHARSET_GBK = "GBK";
    //               
    const RESPONSE_OUTER_NODE_QR = 'alipay_open_app_qrcode_create_response';
    //token            
    const RESPONSE_OUTER_NODE_AUTH_TOKEN = 'alipay_system_oauth_token_response';
    //                
    const RESPONSE_OUTER_NODE_USER_INFO = 'alipay_user_info_share_response';
    //           
    const RESPONSE_OUTER_NODE_ERROR_RESPONSE = 'error_response';
    
    const STATUS_CODE_SUCCESS = 10000;
    const STATUS_CODE_EXCEPT = 20000;
    getAmpUser InfoByAuthCode 방법
    이 방법 은 사용자 정 보 를 얻 는 인터페이스 방법 으로 클 라 이언 트 가 전달 하 는 code 만 들 어가 면 사용자 의 완전한 정 보 를 얻 을 수 있다.
    getAmpToken 방법
    이 방법 은 알 리 페 이 인 터 페 이 스 를 가 져 오 는 token 방법 입 니 다.공용 방법 입 니 다.뒤의 모든 알 리 페 이 를 호출 할 때 이 방법 으로 먼저 token 을 가 져 올 수 있 습 니 다.
    getResponse 방법
    각 알 리 페 이의 인 터 페 이 스 를 호출 하 는 것 을 고려 하여 이 방법 을 밀봉 하 는 것 은 인터페이스 가 성공 한 후의 정 보 를 편리 하 게 캡 처 하여 코드 의 읽 기 성 을 높이 기 위해 서 이다.
    getApiPubbParam 방법
    이 방법 은 버 전 번호,인 코딩,appid,서명 유형 등 기본 업무 매개 변 수 를 포함 하여 공공 인 자 를 얻 기 위 한 것 입 니 다.
    getSign Content 방법
    이 방법 은 서명 한 내용 을 가 져 오 는 것 입 니 다.입 참 은 배열 이 고 마지막 으로 출력 한 것 은 매개 변수의 연결 문자열 입 니 다.
    buildApiBuisinessParam($businessParam,$apiMethod)
    이것 은 api 독립 된 업무 매개 변수 부분 을 구축 하 는 방법 입 니 다.businessParam 매개 변 수 는 알 리 페 이 각 인터페이스의 업무 매개 변수 부분(공공 매개 변수 나 가기)입 니 다.$apiMethod 는 해당 하 는 인터페이스 방법 이름 입 니 다.예 를 들 어 token 을 가 져 오 는 방법 은 alipay.system.oauth.token 입 니 다.
    서명 도움말 클래스
    
    <?php
    /**
     * Created by PhpStorm.
     * User: Auser
     * Date: 2018/12/4
     * Time: 15:37
     */
    
    namespace App\Http\Helper;
    
    /**
     *$rsa2 = new Rsa2();
     *$data = 'mydata'; //      
     *$strSign = $rsa2->createSign($data);   //    
     *$is_ok = $rsa2->verifySign($data, $strSign); //    
     */
    class RsaHelper
    {
    
      private static $PRIVATE_KEY;
      private static $PUBLIC_KEY;
    
    
      function __construct(){
        self::$PRIVATE_KEY = config('param.amp.private_key');
        self::$PUBLIC_KEY = config('param.amp.public_key');
      }
    
      /**
       *     
       * @return bool|resource
       */
      private static function getPrivateKey()
      {
        $privKey = self::$PRIVATE_KEY;
        $privKey = "-----BEGIN RSA PRIVATE KEY-----".PHP_EOL.wordwrap($privKey, 64, PHP_EOL, true).PHP_EOL."-----END RSA PRIVATE KEY-----";
        ($privKey) or die('          ,   RSA    ');
        error_log('private_key is ===========>: '.$privKey);
        return openssl_pkey_get_private($privKey);
      }
      /**
       *     
       * @return bool|resource
       */
      private static function getPublicKey()
      {
        $publicKey = self::$PUBLIC_KEY;
        $publicKey = "-----BEGIN RSA PRIVATE KEY-----".PHP_EOL.wordwrap($publicKey, 64, PHP_EOL, true).PHP_EOL."-----END RSA PRIVATE KEY-----";
        error_log('public key is : ===========>'.$publicKey);
        return openssl_pkey_get_public($publicKey);
      }
      /**
       *     
       * @param string $data   
       * @return null|string
       */
      public function createSign($data = '')
      {
        // var_dump(self::getPrivateKey());die;
        if (!is_string($data)) {
          return null;
        }
        return openssl_sign($data, $sign, self::getPrivateKey(),OPENSSL_ALGO_SHA256 ) ? base64_encode($sign) : null;
      }
      /**
       *     
       * @param string $data   
       * @param string $sign   
       * @return bool
       */
      public function verifySign($data = '', $sign = '')
      {
        if (!is_string($sign) || !is_string($sign)) {
          return false;
        }
        return (bool)openssl_verify(
          $data,
          base64_decode($sign),
          self::getPublicKey(),
          OPENSSL_ALGO_SHA256
        );
      }
    }
    호출
    
    $originUserData = AmpHelper::getAmpUserInfoByAuthCode($code);
    echo $originUserData;
    getAmpUser InfoByAuthCode 방법 을 주의 하 십시오.인 터 페 이 스 를 성공 적 으로 호출 하면 알 리 페 이 사용자 의 정확 한 정 보 를 되 돌려 줍 니 다.예 를 들 어 다음 과 같 습 니 다.
    
    {
      "alipay_user_info_share_response": {
        "code": "10000",
        "msg": "Success",
        "user_id": "2088102104794936",
        "avatar": "http://tfsimg.alipay.com/images/partner/T1uIxXXbpXXXXXXXX",
        "province": "   ",
        "city": "  ",
        "nick_name": "     ",
        "is_student_certified": "T",
        "user_type": "1",
        "user_status": "T",
        "is_certified": "T",
        "gender": "F"
      },
      "sign": "ERITJKEIJKJHKKKKKKKHJEREEEEEEEEEEE"
    }
    구 덩이 를 밟다
  • 개발 하기 전에 사용자 의 권한 수여 절차 안내 문 서 를 자세히 읽 어야 합 니 다.그렇지 않 으 면 오류 가 발생 할 수 있 습 니 다
  • 사용자 정보 인터페이스 에 대해 권한 수여 정보 인 터 페 이 스 를 얻 는 데 명확 한 설명 을 하지 않 았 기 때문에 먼저 정리 해 야 한다
  • 알 리 페 이의 서명 체 제 는 위 챗 과 크게 다르다.위 챗 애플 릿 개발 에 익숙 한 사람 에 게 처음에는 적응 하지 못 했 을 수도 있 기 때문에 sdk 의 실현
  • 을 많이 봐 야 한다.
    이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

    좋은 웹페이지 즐겨찾기