php oauth2 认证,laravel之passport oauth2认证之授权码详解

包地址

composer require laravel/passport 1.0.*

config/app.php

Laravel\Passport\PassportServiceProvider::class,

生成表

php artisan migrate

3df8b2b6d533

image.png

分析表

oauth_access_tokens 通过认证token表

3df8b2b6d533

image.png

oauth_auth_codes 认证code表

3df8b2b6d533

image.png

oauth_clients认证客户端

3df8b2b6d533

image.png

oauth_personal_access_clients 个人授权客户端

3df8b2b6d533

image.png

oauth_refresh_tokens刷新token表

3df8b2b6d533

image.png

配置

app/auth.php

'guards' => [

'web' => [

'driver' => 'session',

'provider' => 'users',

],

'api' => [

'driver' => 'passport',//这里改成passport

'provider' => 'users',

],

],

app/User.php

use Laravel\Passport\HasApiTokens;

use Illuminate\Notifications\Notifiable;

namespace App;

use Laravel\Passport\HasApiTokens;

use Illuminate\Notifications\Notifiable;

use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable

{

use HasApiTokens, Notifiable;

/**

* The attributes that are mass assignable.

*

* @var array

*/

protected $fillable = [

'name', 'email', 'password',

];

/**

* The attributes that should be hidden for arrays.

*

* @var array

*/

protected $hidden = [

'password', 'remember_token',

];

}

Laravel\Passport\HasApiTokens;

namespace Laravel\Passport;

use Illuminate\Container\Container;

trait HasApiTokens

{

/**

*当前的存取令牌for the认证用户。

*

* @var \Laravel\Passport\Token

*/

protected $accessToken;

/**

* 获取所有用户注册的OAuth-客户端。

*

* @return \Illuminate\Database\Eloquent\Relations\HasMany

*/

public function clients()

{

return $this->hasMany(Client::class, 'user_id');

}

/**

* 获取用户的所有访问令牌。

*

* @return \Illuminate\Database\Eloquent\Collection

*/

public function tokens()

{

return $this->hasMany(Token::class, 'user_id')->orderBy('created_at', 'desc');

}

/**

* 获取用户正在使用的当前访问令牌

*

* @return \Laravel\Passport\Token|null

*/

public function token()

{

return $this->accessToken;

}

/**

* 确定当前API令牌是否具有给定范围。

*

* @param string $scope

* @return bool

*/

public function tokenCan($scope)

{

return $this->accessToken ? $this->accessToken->can($scope) : false;

}

/**

* 为用户创建一个新的个人访问令牌。

*

* @param string $name

* @param array $scopes

* @return \Laravel\Passport\PersonalAccessTokenResult

*/

public function createToken($name, array $scopes = [])

{

return Container::getInstance()->make(PersonalAccessTokenFactory::class)->make(

$this->getKey(), $name, $scopes

);

}

/**

*为用户设置当前访问令牌

.

*

* @param \Laravel\Passport\Token $accessToken

* @return $this

*/

public function withAccessToken($accessToken)

{

$this->accessToken = $accessToken;

return $this;

}

}

app/Providers/AuthServiceProvider.php

boot方法中调用Passport::routes方法

namespace App\Providers;

use Laravel\Passport\Passport;

use Illuminate\Support\Facades\Gate;

use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;

class AuthServiceProvider extends ServiceProvider

{

/**

* The policy mappings for the application.

*

* @var array

*/

protected $policies = [

'App\Model' => 'App\Policies\ModelPolicy',

];

/**

* Register any authentication / authorization services.

*

* @return void

*/

public function boot()

{

$this->registerPolicies();

Passport::routes();

//

}

}

Passport::routes();

www/laravel53/vendor/laravel/passport/src/Passport.php

public static function routes($callback = null, array $options = [])

{

$callback = $callback ?: function ($router) {

$router->all();

};

/*

*上面等价于

$callback = $callback ? $callback: function ($router) {

$router->all();

};

*/

$options = array_merge([

'namespace' => '\Laravel\Passport\Http\Controllers',

'prefix' => 'oauth',

], $options);

Route::group($options, function ($router) use ($callback) {

$callback(new RouteRegistrar($router));

});

}

如果设置了回调函数,则回调函数的返回自定义的,如果没有,则调用回调函数的所有路由,这里回调了RouteRegistrar这个,这合并传入进来的参数,$options覆盖前面的,

'namespace' => '\Laravel\Passport\Http\Controllers',

'prefix' => 'oauth',

如果你需要全部重写,则修改命名空间和前缀,或者是只修改前缀。

RouteRegistrar的all()

public function all()

{

$this->forAuthorization();

$this->forAccessTokens();

$this->forTransientTokens();

$this->forClients();

$this->forPersonalAccessTokens();

}

forAuthorization()注册认证路由

public function forAuthorization()

{

$this->router->group(['middleware' => ['web', 'auth']], function ($router) {

$router->get('/authorize', [

'uses' => 'AuthorizationController@authorize',

]);

$router->post('/authorize', [

'uses' => 'ApproveAuthorizationController@approve',

]);

$router->delete('/authorize', [

'uses' => 'DenyAuthorizationController@deny',

]);

});

}

forAccessTokens();注册用于检索和发布访问令牌的路由。

public function forAccessTokens()

{

$this->router->post('/token', [

'uses' => 'AccessTokenController@issueToken',

'middleware' => 'throttle'

]);

$this->router->group(['middleware' => ['web', 'auth']], function ($router) {

$router->get('/tokens', [

'uses' => 'AuthorizedAccessTokenController@forUser',

]);

$router->delete('/tokens/{token_id}', [

'uses' => 'AuthorizedAccessTokenController@destroy',

]);

});

}

$this->forTransientTokens(); 刷新令牌路由

public function forTransientTokens()

{

$this->router->post('/token/refresh', [

'middleware' => ['web', 'auth'],

'uses' => 'TransientTokenController@refresh',

]);

}

$this->forClients();注册管理客户所需的路由。

public function forClients()

{

$this->router->group(['middleware' => ['web', 'auth']], function ($router) {

$router->get('/clients', [

'uses' => 'ClientController@forUser',

]);

$router->post('/clients', [

'uses' => 'ClientController@store',

]);

$router->put('/clients/{client_id}', [

'uses' => 'ClientController@update',

]);

$router->delete('/clients/{client_id}', [

'uses' => 'ClientController@destroy',

]);

});

}

$this->forPersonalAccessTokens();注册管理个人访问令牌所需的路由。

public function forPersonalAccessTokens()

{

$this->router->group(['middleware' => ['web', 'auth']], function ($router) {

$router->get('/scopes', [

'uses' => 'ScopeController@all',

]);

$router->get('/personal-access-tokens', [

'uses' => 'PersonalAccessTokenController@forUser',

]);

$router->post('/personal-access-tokens', [

'uses' => 'PersonalAccessTokenController@store',

]);

$router->delete('/personal-access-tokens/{token_id}', [

'uses' => 'PersonalAccessTokenController@destroy',

]);

});

}

JSON API

随便找个访问的页面,映入一个JS,例如

Route::get('/rr', function () {

echo '';

$a=Auth::user()->toArray();

print_r($a);

});

axios.get('/oauth/clients')

.then(response => {

console.log(response.data);

});

3df8b2b6d533

image.png

POST /oauth/clients

[图片上传中...(image.png-c74593-1528777113310-0)]

const data = {

name: 'Client Name',

redirect: 'http://example.com/callback'

};

axios.post('/oauth/clients', data)

.then(response => {

console.log(response.data);

})

.catch (response => {

// List errors on response...

});

自动将当前登录的帐号写入,这些测试都需要用户登录之后才能操作。否则没有权限访问,因为给了中间件auth

PUT /oauth/clients/{client-id}

const data = {

name: 'New Client Name',

redirect: 'http://example.com/callback'

};

axios.put('/oauth/clients/' + clientId, data)

.then(response => {

console.log(response.data);

})

.catch (response => {

// List errors on response...

});

3df8b2b6d533

image.png

3df8b2b6d533

image.png

3df8b2b6d533

image.png

只是改了name和回调地址

public function update(Request $request, $clientId)

{

if (! $request->user()->clients->find($clientId)) {

return new Response('', 404);

}

$this->validation->make($request->all(), [

'name' => 'required|max:255',

'redirect' => 'required|url',

])->validate();

return $this->clients->update(

$request->user()->clients->find($clientId),

$request->name, $request->redirect

);

}

DELETE /oauth/clients/{client-id}

axios.delete('/oauth/clients/' + clientId,data)

.then(response => {

console.log(response.data);

});

请求令牌

这里先新建立一个用户

然后创建一个新的客户端绑定这个用户

php artisan passport:client

[root@localhost laravel53]# php artisan passport:client

Which user ID should the client be assigned to?:

> 2

What should we name the client?:

> bstbst2

Where should we redirect the request after authorization? [http://localhost/auth/callback]:

> http://192.168.91.130:82/auth/callback2

New client created successfully.

Client ID: 11

Client secret: N6Z60B51FRkG2PSyQ9B26v79qJF51NnZo8S6P826

3df8b2b6d533

image.png

定义路由

api.php

Route::get('/redirect2', function (){

$query = http_build_query([

'client_id' => '11',

'redirect_uri' => 'http://192.168.91.130:82/auth/callback2',

'response_type' => 'code',

'scope' => '',

]);

return redirect('http://192.168.91.130:82/oauth/authorize?' . $query);

});

web.php

Route::get('/auth/callback2', function (\Illuminate\Http\Request $request) {

$http = new GuzzleHttp\Client;

echo $request->get('code');;echo '
';

$response = $http->post('http://192.168.91.130:82/oauth/token', [

'form_params' => [

'grant_type' => 'authorization_code',

'client_id' => '11', // your client id

'client_secret' => 'N6Z60B51FRkG2PSyQ9B26v79qJF51NnZo8S6P826', // your client secret

'redirect_uri' => 'http://192.168.91.130:82/auth/callback2',

'code' => $request->get('code'),

],

]);

return json_decode((string) $response->getBody(), true);

});

现在浏览器打开

http://192.168.91.130:82/api/redirect2

3df8b2b6d533

image.png

服务器返回地址拦带code

http://192.168.91.130:82/auth/callback2?code=def5020071cfabda8770c9e78ed7706f0905ca16a7acd077054aa7570c60d5600b41e7e4c3a2041b2073edd83cf963bacdea9245ba3e47cbc3c65a06118325b7217217b6279cd21016487cbbf00cb5ce95092edb9c341d5f7eeab9000a050d8a2ed6ae6e0f32ca2146c6cbdb414142be035369244e4e4df5e83511a80679d988bbfccf54533f0aadf3b983db764192086bf4175484bc34b5dc21d5a9ba3b41b63bcd170dbedde5a9bd131e720f2b62d17ca0d25461f13398b7f249121f256a610cb8b931fbfcd5b89bd5bd603b712a4ad977b2d6b3f2b9c29fa119efd26339771dd119ad483e12aae7a4fa9ab8a5614bb239d117fe6431022cef0166cf2a9d922fbdb99ef0bad035188283e6f2b7973bf3de103d1097184031223a9b743f558f86130e250b6f6236c981ec913620ff290aef7e70007f01c9c8188686fcd9cbd31fa90da1ee0107065bf46b1486e3b746d06535a33ba04e5dbb24ad4b46dbab1e258779606ec505b8a0c8cc19cb

因为我们再回调里面直接写了,post过去认证,这里返回

{

"token_type": "Bearer",

"expires_in": 31535999,

"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6IjJhNThkZDdiZjIxNGZkYjY1MDVmODkxMWUxZTFkODFjMjdmNzEzOTVkYmM4MmM5ODgwNGI0ZmYxYjkzZDVlZmI3ODk1N2IzYzVlMDNlZTQ0In0.eyJhdWQiOiIxMSIsImp0aSI6IjJhNThkZDdiZjIxNGZkYjY1MDVmODkxMWUxZTFkODFjMjdmNzEzOTVkYmM4MmM5ODgwNGI0ZmYxYjkzZDVlZmI3ODk1N2IzYzVlMDNlZTQ0IiwiaWF0IjoxNTI4NzkyMjExLCJuYmYiOjE1Mjg3OTIyMTEsImV4cCI6MTU2MDMyODIxMSwic3ViIjoiMiIsInNjb3BlcyI6W119.GQBOIlXnQAIMMAEDwaR8NpOumTeIm9JD3MkTZl_VMek_KcGT5P7Bwuj5tMV-k1-tXUp4u_-iLrAhzfT-1BymywaZNwsiSu0Ehzs6V0d22JIRzY0EkT4gfuRLw51AjiB5zUSlSjEqulRY8NFjplcSDidDopzIwpB-YzWCvB8RZ0NXZcdLxfTN4cUcYIlI3UMorGM_7lGecZ-LVc0ZQ6GzDsteC-Cbhnlcy7oT_xY-aGyNLgfAe_ZP2qofiZv22ufdnypcdg7CtHWM9oAiUhssdO8imvAW00Y3h0K8nQVDVcC9N5v93TfxeED376pVoFYSgR9vjzPtMOKtu7irHjVv_Og1cyt83i5-betgO_URMvBTD986MZ5N7-5bfp_WG416JaeNy3xhK1m-t_SBdb71_9w8uo25KsPwfsAGTE1HAO-jb2ntcYnlcVLfR0_c7AXWTluLGnYvwWyyr76JIDMEunfp4i9Qzuzcj2dcbt1VrlLDSGuhGD8PRSdrCJQUs95M06IMaWtz73w_rxJxfDNmX4Q17mrbREncBpmhbuZ6JzOdWcC2F8T5D3OJJpghDKj6TvNMG97ZDMIPaesAG0OPFXf2U_wLCWOB-PXW92wRQufWgZJUcHekX7C6CVDdT2FyXCMvu_9pt_4ZSIRnQwrfOOfKGf1U7UU6VLtv5THsDiI",

"refresh_token": "def5020057c3a82b1607265f777db6ba75cd10dc4aa10eda4271a814d613ca5af6a032be9697e91d1ce4f792bf32a4a77734babc9ab94ded306f32f05ebe98735c0858652d7eb5ad1e2c02a665df38149fe2f53df19ebbc76afcdb31d00284fa4a22c3b17da4d5d3db9719f0e9de6739154406aae7e55d40ef4d4e06d28a949e77ce6fa7166403e1bd0e728b76dbae85d78b86b0f39765466c13a17a40bd086a99c821b9222b3e93540e3c2b4c63da59a10017ce96a0166a26596f23cd6710aee5ed0723d2ceee65b9a41a2515a29d10488c0650d8978c4e3669022bb83e0503d552120071ff7b08ac81c70b83a5463a7f1d451cbcf423e0493d5e3b71754325c10056415aaf5696cd5010cc0dcdd44c73a011795c91da6c87555e4d6eccf9eb5a9482a47911d7983936d3d5fed3b6765766e5871d4e9dbb4d07c58b6de309e99f56433b0e3170718797e31e22f5a2afe315188d17b70c4060d386e6da9bd33c66e5"

}

这个时候看下数据库,以下截图是后来补的,可能跟之前的客户端对不上,之前是11,现在是13,这里参考下就行

刷新token表

3df8b2b6d533

image.png

有效期默认是365天,今天是6-12号

token表

3df8b2b6d533

image.png

认证码表

3df8b2b6d533

image.png

如果你想定义刚才那个授权界面,可以

发布的视图位于 resources/views/vendor/passport:

php artisan vendor:publish --tag=passport-views

刷新令牌

Route::get('/auth/callback', function (Request $request) {

$http = new GuzzleHttp\Client;

$response = $http->post('http://laravel55.dev/oauth/token', [

'form_params' => [

'grant_type' => 'authorization_code',

'client_id' => '11', // your client id

'client_secret' => 'N6Z60B51FRkG2PSyQ9B26v79qJF51NnZo8S6P826', // your client secret

'redirect_uri' => 'http://192.168.91.130:82/auth/callback',

'code' => $request->code,

],

]);

return json_decode((string) $response->getBody(), true);

});

以上是code授权oauth2.0

下一篇讲密码授权令牌

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是一个简单的OAuth 2.0授权认证的Java实例: 首先,需要引入Maven依赖,包括Spring Security OAuth2和Spring Web MVC: ```xml <dependency> <groupId>org.springframework.security.oauth</groupId> <artifactId>spring-security-oauth2</artifactId> <version>2.3.6.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.3.8</version> </dependency> ``` 接着,创建一个`WebSecurityConfigurerAdapter`类,用于配置Spring Security: ```java @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private UserDetailsService userDetailsService; @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/oauth/**").permitAll() .anyRequest().authenticated() .and().formLogin().permitAll(); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder()); } } ``` 在上面的代中,我们配置了允许所有用户访问`/oauth/**`路径下的资源,其他路径需要进行身份验证,使用BCrypt密器进行密加密。 接着,创建一个`AuthorizationServerConfigurerAdapter`类,用于配置OAuth2认证服务器: ```java @Configuration @EnableAuthorizationServer public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter { @Autowired private AuthenticationManager authenticationManager; @Autowired private UserDetailsService userDetailsService; @Autowired private DataSource dataSource; @Bean public TokenStore tokenStore() { return new JdbcTokenStore(dataSource); } @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { clients.jdbc(dataSource); } @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { endpoints.authenticationManager(authenticationManager) .userDetailsService(userDetailsService) .tokenStore(tokenStore()); } } ``` 在上面的代中,我们配置了使用JDBC进行令牌存储,并使用数据源配置客户端详情服务。 最后,创建一个`ResourceServerConfigurerAdapter`类,用于配置OAuth2资源服务器: ```java @Configuration @EnableResourceServer public class ResourceServerConfig extends ResourceServerConfigurerAdapter { @Override public void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/api/**").authenticated() .anyRequest().permitAll(); } } ``` 在上面的代中,我们配置了只允许经过身份验证的用户访问`/api/**`路径下的资源。 以上是一个简单的OAuth 2.0授权认证的Java实例。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值