Laravel在第三方QQ登陆后的逻辑处理

Laravel在第三方QQ登陆后的逻辑处理

源码详见:https://gitee.com/liuzhenqing/laravel-bbs

如果直接看到了本篇文章先看一下前面的一篇文章https://blog.csdn.net/qq_25615395/article/details/80251455
现在没有完成的就是当用户使用qq登陆的时候应该强制移步到修改个人资料的页面,因为还没有开发,以后完善

1. 给用户的表添加qq的字段。写在数据库迁移文件中database/migrations/20xx_xx_xx_xxxxxx_add_outh_field_to_users_table.php

在现在是为了将github的登陆功能添加进来,也把github需要添加的字段写进来

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class AddOuthFieldToUsersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::table('users', function (Blueprint $table) {
            $table->integer('github_id')->nullable();
            $table->string('github_name')->nullable();
            $table->string('github_url')->nullable();
            $table->string('qq_openid')->nullable();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table('users', function (Blueprint $table) {
            $table->integer('github_id')->nullable();
            $table->string('github_name')->nullable();
            $table->string('github_url')->nullable();
            $table->string('qq_openid')->nullable();
        });
    }
}

2. 重写第三方服务的提供者

App\Providers利用命令php artsian make:provider OAuthServiceProvider创建OAuthServiceProvider.php

在上一章节的添加在事件监听器中的QQ登陆处理给取消掉
又因为采用的是自定义的服务,因此注入容器中服务提供者在app.php可以去除掉

<?php

namespace App\Providers;

use App\Base\OAuth\QQProvider;
use Illuminate\Support\ServiceProvider;

class OAuthServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap the application services.
     *
     * @return void
     */
    public function boot()
    {
        $this->app->make('Laravel\Socialite\Contracts\Factory')->extend('qq', function ($app) {
            $config = $app['config']['services.qq'];
            return new QQProvider(
                $app['request'],
                $config['client_id'],
                $config['client_secret'],
                $config['redirect']
            );
        });
    }

    /**
     * Register the application services.
     *
     * @return void
     */
    public function register()
    {
        //
    }
}

3. 创建QQ服务的提供者,位置我是写在了app\Base\OAuth\QQProvider.php

<?php

namespace App\Base\OAuth;
use Laravel\Socialite\Two\AbstractProvider;
use Laravel\Socialite\Two\ProviderInterface;
use Laravel\Socialite\Two\User;

class QQProvider extends AbstractProvider implements ProviderInterface
{
    /**
     * @var string
     */
    private $openId;


    protected $scopes = ['get_user_info'];


    protected function getTokenUrl()
    {

        return 'https://graph.qq.com/oauth2.0/token';
    }

    protected function mapUserToObject(array $user)
    {

        return (new User())->setRaw($user)->map([
            'id' => $this->openId,
            'nickname' => $user['nickname'],
            'name' => null,
            'email' => null,
            'avatar' => $user['figureurl_qq_2'],
            'gender' => $user['gender']
        ]);

    }

    /**
     * {@inheritdoc}.
     *
     * @see \Laravel\Socialite\Two\AbstractProvider::getTokenFields()
     */
    protected function getTokenFields($code)
    {

        return array_merge(parent::getTokenFields($code), [
            'grant_type' => 'authorization_code',
        ]);
    }

    /**
     * {@inheritdoc}.
     *
     * @see \Laravel\Socialite\Two\AbstractProvider::getAccessToken()
     */
    public function getAccessTokenResponse($code)
    {

        $response = $this->getHttpClient()->get($this->getTokenUrl(), [
            'query' => $this->getTokenFields($code),
        ]);

        $content = $response->getBody()->getContents();

        parse_str($content, $result);
        return $result;
    }

    protected function getUserByToken($token)
    {

        $response = $this->getHttpClient()->get('https://graph.qq.com/oauth2.0/me?access_token='.$token);

        $this->openId = json_decode($this->removeCallback($response->getBody()->getContents()), true)['openid'];

        $response = $this->getHttpClient()->get(
            "https://graph.qq.com/user/get_user_info?access_token=$token&openid={$this->openId}&oauth_consumer_key={$this->clientId}"
        );


        $res = json_decode($this->removeCallback($response->getBody()->getContents()), true);

        return $res;

    }

    protected function getAuthUrl($state)
    {

        return $this->buildAuthUrlFromBase('https://graph.qq.com/oauth2.0/authorize', $state);
    }

    /**
     * @param mixed $response
     *
     * @return string
     */
    protected function removeCallback($response)
    {

        if (strpos($response, 'callback') !== false) {
            $lpos = strpos($response, '(');
            $rpos = strrpos($response, ')');
            $response = substr($response, $lpos + 1, $rpos - $lpos - 1);
        }
        return $response;
    }
}

4. 下面就是最重要的登陆之后的逻辑处理了—控制器App\Http\Controllers\Auth\SocialiteLoginController.php

 /**
     * 处理第三方登录的回调
     *
     * @param $service
     */
    public function handleProviderCallback($service)
    {
        $user = Socialite::driver($service)->user();
        $manager = new OAuthManager($service);
        $manager->auth($user);

        return redirect('/');
        // dd($user);
    }

4. 下面就是最重要的登陆之后的逻辑处理了—第三方登陆处理中心app\Base\OAuth\OAuthManager.php

这里也将github的登陆处理给贴出来了,具体的可以根据需要修改
也许我这里的用户表跟你的不一样,请酌情修改就行了

<?php
namespace App\Base\OAuth;
use App\Models\User;
use Illuminate\Support\Facades\Auth;

class OAuthManager
{

    protected $driver;

    public function __construct($driver)
    {
        $this->driver = $driver;
    }


    public function auth($user){

        $method = 'authWith'.ucfirst($this->driver);
        if (! method_exists($this,$method)){
            return false;
        }
        return $this->$method($user);

    }

    protected function authWithQq($user){

        // 如果已经存在 -> 登录
        $current_user = User::where('qq_openid',$user->id)->first();
        if ($current_user){
            Auth::login($current_user);
            return $current_user;
        }
        // 创建用户
        // 判断有重复昵称则拼接随机字符串

        $username = $user->nickname;
        // 如果的qq好的邮箱为空的
        if($user->email == null){

        }
        if (User::query()->where('name',$user->nickname)->first()){
            $username = $username.'_'.str_random(5);
        }

        $current_user = User::create([
            'qq_openid' =>$user->id,
            'name' => $username,
            'email' => $user->email,
            'is_active' => 1,
            'avatar' => $user->avatar,
            'password' => '',
            'confirmation_token' => str_random(40),
        ]);

        Auth::login($current_user);
        return $current_user;
    }

    // 存储github用户信息
    protected function authWithGithub($user){

        // 如果已经存在 -> 登录
        $current_user = User::where('github_id',$user->id)->first();
        if ($current_user){
            Auth::login($current_user);
            return $current_user;
        }

        $username = $user->nickname;
        if (User::query()->where('name',$user->nickname)->first()){
            $username = $username.'_'.str_random(5);
        }
        // 创建用户
        $current_user = User::create([
            'name' => $username,
            'email' => $user->email,
            'activated' => 1,
            'avatar' => $user->avatar,
            'github_id' => $user->id,
            'github_name' => $user->name,
            'github_url' => $user->user['url'],
            'password' => ''

        ]);

        $current_user->activated = true;
        $current_user->save();
        Auth::login($current_user);
        return $current_user;
    }
}

猜你喜欢

转载自blog.csdn.net/qq_25615395/article/details/80256098
今日推荐