| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283 | <?phpnamespace App\Http\Controllers\Xchengxu\Oauth;use App\Modules\User\Services\UserService;use App\Modules\Xcx\Services\XcxSendOrderService;use Illuminate\Http\Request;use App\Http\Controllers\Controller;use App\Modules\User\Models\User;use App\Modules\User\Models\Xcxuser;use Log;use JWTAuth;use GuzzleHttp\Client;class UsersController extends Controller{    /**     * @apiDefine Login 登录     */    /**     * @apiVersion 1.0.0     * @apiDescription 登录     * @api {post} login 登录     * @apiParam  {String}  js_code js_code     * @apiParam  {Int}     distribution_channel_id distribution_channel_id     * @apiParam  {String}  sign    签名     * @apiGroup Login     * @apiName index     * @apiSuccess {int}         code 状态码     * @apiSuccess {String}      msg  信息     * @apiSuccess {object}      data 结果集     * @apiSuccess {String}      data.token token     * @apiSuccess {Int}         data.time 过期时间     * @apiSuccessExample {json} Success-Response:     *     HTTP/1.1 200 OK     *     {     *       code: 0,     *       msg: "",     *       data:  {     *            token:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx,     *            time:123455     *           }     *       }     */    public function index(Request $request)    {        Log::info($request->all());        //$distribution_channel_id = $request->input('distribution_channel_id', '');        //海报推广的参数        $scene = $request->input('scene', '');        $js_code = $request->input('js_code');        $sign = $request->input('sign');        $encryptedData = $request->input('encryptedData');        $iv = $request->input('iv');        //参数推广的参数        $channel_key = $request->input('channel_key',0);        $sign = 1;        if (empty($js_code)  || empty($sign)) {            return response()->error('PARAM_ERROR');        }        $distribution_channel_id = 14;        $uid = 0;        $u = 0;        //解析海报推广的参数        if($scene){            $scene_arr = explode('_',$scene);            $distribution_channel_id = (int)$scene_arr[0];            $uid = $scene_arr[1];            $u = $scene_arr[2];        }        //解析参数推广的参数        if($channel_key){            $channel_key =(int)$channel_key;            $channel_info = XcxSendOrderService::getChannelIdBySendOrderId($channel_key);            if($channel_info){                $distribution_channel_id = $channel_info->distribution_channel_id;                $u = $channel_key;            }        }        if ($sign !== _sign(compact('openid', 'distribution_channel_id', 'unionid'), 'Uv%vkPI5K8Opqoww')) {            //return response()->error('PARAM_ERROR');        }        $login_info = $this->getUserWeixinInfo($js_code);        $appid = 'wxa0c8331eba3b34d5';        $status = $this->decryptData($appid,$login_info['session_key'],$encryptedData,$iv,$user_info);        if($status != ErrorCode::$OK){            return response()->error('PARAM_ERROR');        }        if (!$user_info) response()->error('PARAM_ERROR');        $user_info = json_decode($user_info,1);        if (!isset($user_info['openId']) || !isset($user_info['unionId'])) {            return response()->error('PARAM_ERROR');        }        $openid = $user_info['openId'];        $unionid = $user_info['unionId'];        $user = $this->createUser(compact('openid', 'distribution_channel_id', 'unionid','uid','u'),$user_info);        if ($user) {            $uid = $user->id;            $time = time() + 7200;            $token = JWTAuth::fromUser($user);            return response()->success(compact('token', 'time','uid'));        } else {            return response()->error('PARAM_ERROR');        }    }    /**     * 授权用户信息     * @param $data     * @return bool     */    protected function createUser($data,$user_info)    {        //compact('openid', 'distribution_channel_id', 'unionid','uid','u')        //用户已经是小程序用户了        $xcx_user = Xcxuser::where('unionid',$data['unionid'])            ->where('distribution_channel_id',$data['distribution_channel_id'])            ->select('uid')            ->first();        if($xcx_user){            return User::find($xcx_user->uid);        }        $info = [];        if(isset($user_info['city']) && !empty($user_info['city'])) {$info['city'] = $user_info['city'];}        if(isset($user_info['province']) && !empty($user_info['province'])){ $info['province'] = $user_info['province'];}        if(isset($user_info['country']) && !empty($user_info['country'])){ $info['country'] = $user_info['country'];}        if(isset($user_info['gender']) && !empty($user_info['gender'])) {$info['sex'] = $user_info['gender'];}        if(isset($user_info['nickName']) && !empty($user_info['nickName'])) {$info['nickname'] = $user_info['nickName'];}        if(isset($user_info['avatarUrl']) && !empty($user_info['avatarUrl'])) {$info['head_img'] = $user_info['avatarUrl'];}        //从推广进来的一般会有uid        if($data['uid']){            Xcxuser::create([                'uid'=>$data['uid'],                'openid'=>$data['openid'],                'unionid'=>$data['unionid'],                'distribution_channel_id'=>$data['distribution_channel_id'],                'u'=>$data['u']            ]);            if($info){                UserService::updateInfo($data['uid'],$info);            }            return User::find($data['uid']);        }else{            //直接进入的            $info['openid'] =$data['openid'];            $info['unionid'] =$data['openid'];            $info['distribution_channel_id'] =$data['distribution_channel_id'];            $info['send_order_id'] =$data['u'];            $user =  User::addUser($info);            Xcxuser::create([                'uid'=>$user->id,                'openid'=>$data['openid'],                'unionid'=>$data['unionid'],                'distribution_channel_id'=>$user->distribution_channel_id,                'u'=>$data['u']            ]);            return $user;        }    }    /**     * @apiVersion 1.0.0     * @apiDescription 刷新token     * @api {get} RefreshToken 刷新token     * @apiParam {String}  [token]  token     * @apiHeader {String} [Authorization]  token 两个token任选其一     * @apiGroup Login     * @apiName RefreshToken     * @apiSuccess {int}         code 状态码     * @apiSuccess {String}      msg  信息     * @apiSuccess {object}      data 结果集     * @apiSuccess {String}      data.token token     * @apiSuccess {Int}         data.time 过期时间     * @apiSuccessExample {json} Success-Response:     *     HTTP/1.1 200 OK     *     {     *       code: 0,     *       msg: "",     *       data:  {     *            token:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx,     *            time:123455     *           }     *       }     */    public function RefreshToken()    {        try{            $old_token = JWTAuth::getToken();            $token = JWTAuth::refresh($old_token);            $time = time() + 7200;            return response()->success(compact('token', 'time'));        }catch (\Exception $e){        }        return response()->error('XCX_NOT_LOGIN');    }    private function getUserWeixinInfo($js_code)    {        if (empty($js_code)) {            return false;        }        $url = 'https://api.weixin.qq.com/sns/jscode2session?';        $client = new Client([            'timeout' => 2.0,        ]);        $appid = 'wxa0c8331eba3b34d5';        $secret = '17c01c26dd7873e557710601436774c7';        $grant_type = 'authorization_code';        try {            $res = $client->get($url . http_build_query(compact('js_code', 'appid', 'secret', 'grant_type')))->getBody()->getContents();            Log::info('code 换取 session_key is :');            Log::info($res);            $res = json_decode($res, true);            if (isset($res['errcode'])) {                return false;            }            return $res;        } catch (\Exception $e) {            Log::info($e);            return false;        }    }    /**     * 检验数据的真实性,并且获取解密后的明文.     * @param $encryptedData string 加密的用户数据     * @param $iv string 与用户数据一同返回的初始向量     * @param $data string 解密后的原文     *     * @return int 成功0,失败返回对应的错误码     */    private function decryptData($appid, $sessionKey,$encryptedData, $iv, &$data )    {        if (strlen($sessionKey) != 24) {            return ErrorCode::$IllegalAesKey;        }        $aesKey=base64_decode($sessionKey);        if (strlen($iv) != 24) {            return ErrorCode::$IllegalIv;        }        $aesIV=base64_decode($iv);        $aesCipher=base64_decode($encryptedData);        $result=openssl_decrypt( $aesCipher, "AES-128-CBC", $aesKey, 1, $aesIV);        $dataObj=json_decode( $result );        if( $dataObj  == NULL )        {            return ErrorCode::$IllegalBuffer;        }        if( $dataObj->watermark->appid !=$appid )        {            return ErrorCode::$IllegalBuffer;        }        $data = $result;        return ErrorCode::$OK;    }}class ErrorCode{    public static $OK = 0;    public static $IllegalAesKey = -41001;    public static $IllegalIv = -41002;    public static $IllegalBuffer = -41003;    public static $DecodeBase64Error = -41004;}
 |