小白兔晒黑了

导航

 

1 原理

1 bilibili 提供一个微信登录的连接,用户点击跳转到微信授权服务器

2 用户根据微信授权服务器提示登录微信并确认授权给bilibili

3 微信授权服务器返回用户代理(浏览器)一个授权码

4 用户代理(浏览器)把这个授权码传给bilibili

5 bilibili凭借授权码向微信授权服务器请求令牌

6 微信授权服务器发送令牌给bilibili

2 授权码模式与密码模式的区别

   oauth2支持授权的方式有四种:授权码模式(authorization_code)、密码模式(password)、隐式模式(implicit)、客户端模式(client_credentials)。其中,比较常见的就是授权码模式和密码模式。

2.1 授权码模式的过程

1、封装参数,访问授权服务器登录与授权接口
   接口:http://localhost:8080/oauth/authorize
   参数:response_type client_id scope redirect_uri state
   返回值:code
2、拿到code,获取token
   接口:http://localhost:8080/oauth/token
   参数:client_id client_secret grant_type code redirect_uri state
   返回值:access_token
3、根据token,访问资源
   接口:http://localhost:8080/api/test/hello
   参数:access_token

2.2 密码模式的过程

1、根据用户名密码等参数直接获取token
   接口:http://localhost:8080/oauth/token
   参数:username password grant_type client_id client_secret redirect_uri
   返回值:access_token
2、根据token,访问资源
   接口:http://localhost:8080/api/test/hello
   参数:access_token

可以看出,授权码模式和密码模式有些区别,授权码模式多了一步就是登陆。密码模式直接把用户名和密码交给授权服务器了,所以不用再人为登陆,这也要求用户非常信任该应用。

3 创建服务器端 test.weixin.com

3.1 配置

3.1.1 安装项目

composer create-project --prefer-dist laravel/laravel weixin

3.1.2 配置.env 数据库

3.1.3 安装passport组件

cd weixin
composer require laravel/passport

3.1.4 Laravel\Passport\HasApiTokens Trait添加到App\User 模型中

\app\Models\User.php

3.2 安装前端

 composer require laravel/ui

更新npm版本

linux版本

npm install -g npm@7.12.0

win版本

https://www.jianshu.com/p/caf18c16c2e9

php artisan ui vue --auth
npm install
npn run prod

 

3.3 准备

3.3.1 安装伪造http请求组件

composer require guzzlehttp/guzzle

3.3.2 auth.php配置

\config\auth.php

    'defaults' => [
        'guard' => 'web',
        'passwords' => 'users',
    ],

 

        'api' => [
//            'driver' => 'token',
            'driver' => 'passport',
            'provider' => 'users',
            'hash' => false,
        ],

3.3.3 数据包安装

php artisan migrate

 

 php artisan passport:keys

3.3.4 注册服务

\app\Providers\AuthServiceProvider.php

use Laravel\Passport\Passport;

 

    public function boot()
    {
        $this->registerPolicies();
        Passport::routes();
    }

 

3.3.5 注册一个帐号

 

3.3.6 创建客户端

 php artisan passport:client

SELECT * FROM  `weixin`.`oauth_clients` WHERE user_id = 1

4  创建客户端 test.bili.com

4.1 准备

4.1.1

composer create-project --prefer-dist laravel/laravel my_bilibili

4.1.2 伪造http请求

composer require guzzlehttp/guzzle

4.2 代码部署

百度盘地址

 链接:https://pan.baidu.com/s/1yHXdVu7C7CQzR2ssj9QAXg
提取码:juge

4.2.1   \routes\web.php 

//登录页面
Route::view('/login','login');
$clientId = '2';
$clientSecret= 'yeydzuW6lQJqoV8Py5exDK4rK4wcryhi3CrYqrGc';


//第三方登录 重定向
Route::get('/weixin/login',
  function (\Illuminate\Http\Request $request) use ($clientId) {
      $request->session()->put('state',$state=\Illuminate\Support\Str::random(40));
      
      $query = http_build_query([
        'client_id' => $clientId,
        'redirect_uri' => env('APP_URL').'/auth/callback',
        'response_type' => 'code',
        'scope' => '*',
        'state' => $state,
      ]);
      return redirect('http://test.weixin.com/oauth/authorize?'.$query);
  });


//回调地址 获取code 并随后发出获取token请求
Route::view('/auth/callback','auth_callback');

Route::post('/get/token',function (\Illuminate\Http\Request $request) use(
  $clientId,
  $clientSecret
){
  //csrf 攻击处理
    $state = $request->session()->pull('state');
    throw_unless(
      strlen($state)>0 && $state === $request->params['state'],
      InvaliaArgumentException::class
    );
    
    $form_params = [
        'grant_type'=>'authorization_code',
        'client_id'=>$clientId,
        'client_secret'=>$clientSecret,
        'redirect_uri'=>env('APP_URL').'/auth/callback',
        'code'=>$request->params['code'],
    ];
    $post = ['form_params'=>$form_params];
    $response = (new \GuzzleHttp\Client())->post('http://test.weixin.com/oauth/token',$post);
    return json_decode((string)$response->getBody(),true);
});

//刷新token
Route::view('/refresh/page','refresh_page');

Route::post('/refresh',function(\Illuminate\Http\Request $request) use (
  $clientId ,
  $clientSecret
){
  $http = new GuzzleHttp\Client;
  $url = 'http://test.weixin.com/oauth/token';
  $post = ['form_params'=>[
      'grant_type'      => 'refresh_token',
      'refresh_token'   => $request->params['refresh_token'],
      'client_id'       => $clientId,
      'client_secret'   => $clientSecret
  ]];
  $response = $http->post($url,$post);
  return json_decode((string)$response->getBody(),true);
});

 

4.2.2  登录页面 \resources\views\login.blade.php

<a href="/weixin/login">
    微信登录
</a>

4.2.3 回调页 \resources\views\auth_callback.blade.php

<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
    function GetRequest() {
        var url = location.search; //获取url中"?"符后的字串
        var theRequest = {};
        if (url.indexOf("?") !== -1) {
            var str = url.substr(1);
            strs = str.split("&");
            for (var i = 0; i < strs.length; i++) {
                theRequest[strs[i].split("=")[0]] = decodeURI(strs[i].split("=")[1]);
            }
        }
        return theRequest;
    }
    //调用
    var Request = GetRequest();
    if (Request['error']) {
        // 用户未授权处理
        alert(Request['error']);
    }else
    {
        var code = Request['code'];
        var state = Request['state'];
        axios.post('/get/token', {
            params: {
                code,
                state
            }
        })
            .then(function (response) {
                console.log(response.data);
            });
    }
</script>

4.2.4 刷新token页面 \resources\views\refresh_page.blade.php

refresh_token 里填入刚才生成的refresh_token

<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
    axios.post('/refresh', {
        params: {
            refresh_token: "def50200b1a5c2dff9cc299a046e4151134e94174ee05843bc865aee42f2b6209726b45eebc2a9f1faf91ded3c15c9eecf059f48e6a56f70de9226ebba0e922c18b45f478a46c09612bedce26ad48c587a2e5c5c9d8cb4416d02f4746f6d710f70bd782eaf6ebed659510cb2088f7e72900990dc4871a717e96a9c549549a7e0ca5f1dae695e7ad5f8813d711b27f7cf2f0411d881dc29b889cbec283637a2c50ea761af92fef6374264699d0ec10432c27b8edec7a4754ee6f7550b16af9fdba29e591dd96073a28990a18d8404bf9e0c1a63f491e685ea46959e020228276160fd553078e0384eb036ce90fc1fd6db9da1cf4b2d86cff6c1ac0f2bf9a327bf5a9c03e78b1df518937ff811e9399460bb3aa215addca7ed0068b143f6b5d9e9f2e1498d241b0f71717262a91fde12ccb632d04e3be8d82df146f89ed69326cbee237f48fc295a1ca054ef05bcd9ce0cd8d75e3b9f32b68b543840f6f3cf9775c2"
        }
    })
        .then(function (response) {
            console.log(response.data);
        });
</script>

5 测试

5.1 登录

http://test.bili.com/login

 

生成:

Object {
 token_type: "Bearer", 
expires_in: 31536000, 
access_token: "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOiIyIiwianRpIjoiMjllOTU5ODhjMmE5ZTA4ZWJjODY1MmE0ZGJlMzMxMjgyZWU0NDVhMTgwYjExNjdlZjQzMjA0NGFmMGYwMDA4MDg0NjU1OTJmMTFjNzY3Y2QiLCJpYXQiOjE2MjA4NDIzMzcsIm5iZiI6MTYyMDg0MjMzNywiZXhwIjoxNjUyMzc4MzM3LCJzdWIiOiIyIiwic2NvcGVzIjpbXX0.M6nh-FQ3xHKw1P6PYFhN-ERRksS5ARqANcmseoKFbv4pB_T8YNN33SPRoaOhVaEotN2JzVhzWFd-Q0aizFwDBbhdZHGiw-FeYA_J7jx9Xg8JAkksVegsI9tL1zEenrvHsPY5SktPwI3gUc5Zlwo5bJy_gexzytJ6mkUo1MMEkbCAXGUjNBfxsbIARTbYdCLQsdVudrEcgPomsMtzhB59CtxQJ0A4p9ydvxlawNnY5JJxm98rHUXAkaRIKVYBKDj6MxNJH6pF0E0laowm4j6h7u8pcploZNW5dzwzLM96tth4VrEEtHzaymEREC3sS58IIyaIT1NRSExpjPwa6Zo2algsGTay-yLCcfjCfeWXA0qE-T-8GqB0uvxf257KBHPYIMbUyJR8w1Yg5GcgCZZpXA6gr8JaDdAJJELjeuDkeR4THk4A9GtbLujJVNJHTOXmiQdiMcBgKChvTvQYJOjnp5jMoaSTCa8tOpIHeUBReJjJLkm83PcwULNuLxkI2TSdyawy2Bfgi03mEEc8szCBkKBLmdO41j3LUNuvuUprHC04E16bb1etJsHSy3GscTgebSVkZllKWT-WMEhyDhk_qUpj2J-OrnWuv2FRPd2kzpKN4KS6hSdWSW5samZ9HYQV0ia2rTXL2ya7h7C-cNfeRQ3Z0UZTSUtvaZ_oTiQ9Qt0", 
refresh_token: "def502001b3d0ad3fc789f4099ed64edbda21072a40b8d7e78b5f34ecc9f55eb4e22dd0fe75edc46df0be3c3a63c9e3cea27b3f6ccbcab008df466c9288b78330923f2fd0b8dfef58889a4291f6d3d54f9c1a4d8593f7aba57dbf85cdfd7fd9b0df1ea0ea2323d155f318a6d300c6e8b43192364cf9aef9b3aca2eb6d41e40d0613298c148a3a6bc643b0fffe9f9a984d7820fbd8e701b90324be60ddd33e09a8f878c00bfb9a55624ecd11d58d7f8ffd4e871652fa723d80118b95a4618699f10406d9e36982b574d1d013d9ec1300c599c7b74e4f874b174fc3ac7ceaa3b31aa18da562d5d3eb135fa381db0940207b1467c0cdafcd7985f16e3e82695a02f9f99aa78f9e2fc5f55e65a4059781da3baaa105258d9d9a0950aa7ae0b7d8d7a551af170e205df882ca01ab4b7fdbcd1b0b7d59852e0e01bbf2283785a59315823b35c742925305fe5844608c909389e5add80e96485e3270a2349af5564072b21" }
callback:31:25

5.2 刷新

http://test.bili.com/refresh/page

返回:

Object {
 token_type: "Bearer", 
expires_in: 31536000, 
access_token: "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOiIyIiwianRpIjoiMDJiZGFhOWIxMjI3ZGYyMTI0YTcyNjZjZTViNTNlY2Q2ZTUxMDg0OWM2MmJjNzg4NWZkM2I1YjgzM2QwZjEwZjkyMjJhMzUzMTg2MDRjMDkiLCJpYXQiOjE2MjA4NDQzNTAsIm5iZiI6MTYyMDg0NDM1MCwiZXhwIjoxNjUyMzgwMzUwLCJzdWIiOiIyIiwic2NvcGVzIjpbXX0.XqjyoeUYwUmqYZCBkH9SPFEeGUzSCYhaDBjyaoIj3Eanh462SkuG0f1ryNX1W5oaVyGIEvpn8NsDmTD4zi4prGq5U7ipFOTauGXPH7vMTgOTC5s1iVZuKLyxSHIbzCvCAfznbt5_5o1LfWrM3fKvZhQkF0DHNuL58MWGoQI79TTb8yr3wj9KuOTAFtZ4lHEiIBKlcwiOl9PcbeBFsl9CwzAmEEW05w1NqJkABu8Qmx-LQgiUEuFSmB_NAMMcmHRDiWoT4MvM1OClybq0GSngkSFwkWc1r0BpT1vS38BYKTABkljB7aS_GuFc8HPYpk0AKflPkqKvkdIqA1q9uX5dSfDKwi--OTKHz___1Wmy5pXHAUlqvWWnyL-Q7MTqfMA39imeQ9oANxWOm1_jvvj3-0R-KqEMSTPPp8VsNl6YQV4ZoLtlGxzDhlLYbk_MOSLUq4k4xXVjef9M7kOnsF1Uompkd3tshfaI32p0Ws1deMJ_Jr0xnSV4EkE3kjQ_6DMjmDgQks9La2AqI3CFVpILNcvh1NEMz3bs4NtHnmyjdo1beokNkgxaJyTgySEfYtf-NQyMaPSkDIprjqT_IVLmB3OP1QwBvFJzLI_6JrPjMaxI7QGUbgxJQWxoXxJoqmC25X9MDDRRHuL5z_LkYyCFmqFF8xJbATScT6QJV9UF0Zo", 
refresh_token: "def50200d100a35326e7d524d65c08cbda19255d61082ead0494b20a7f70fceebfcafef2d0c3fd070da0bf4d2ec76011bf87ed38a8f201eb69c896d21ae500f974b94befb124a4c7c1a6e8d05d0e2885f845257ff5a8d89d1da7620e033771f869e3a43f27cebceacc8c15985e3b134a30b799b4e915f762df3c1c845ff021954c6bc601cac9c5d85f80437016c4aaf6bb642da0396301c0b6ab6560ccd06da302b55821cb2e202d27e12f954559d0bb55a12697dd972f802c0c533cd6a6218e264b369fdd5f1c3f80a1fafe9ad66efaf44802c4ada47f23dba0010f3bdb010249f3991a52a17369cf56e1f10b81c3972c1696d0b47257aeb2e62aa7d18019030b6d2e202b7fbc72772d6ab4889b30931a2fa775c80d2fded545ef4657a661bc9b640f5441129dbcc3ca66b1f25fe57cb49ceda29035a75173860c53a90d3e3d5b380892158449a9b1a06aa21ed582851014e411519fcc995ea34c40c1dd970421" }

 

6 参考资料

github地址  https://github.com/John0079/bili

passport手册 https://learnku.com/docs/laravel/8.x/passport/9420

 

7 其他认证

1 Laravel 7 用户认证 Auth ——传统web认证
2 Laravel 7 用户认证 Auth ——内置的API认证
3 Laravel 7 用户认证 Auth ——Passport密码模式认证

posted on 2021-04-22 02:15  小白兔晒黑了  阅读(1565)  评论(0编辑  收藏  举报