Laravel5.3 started using Passport as an API authorization, passport is based on OAuth2, The following article mainly introduces you to the use of passport in Laravel5.5 to achieve Auth authentication method, the text through the sample code introduced in very detailed, the need for friends can refer to, let's take a look at it.
Objective
Recently in writing a front-end separation project, originally wanted to use Jwt-auth + Dingo development, but slightly cumbersome, so think of the Laravel Passport and 5.5 new Api Resource. Laravel Passport is a set of packaged OAuth2 service-side implementations
OAuth is an open network standard for licensing (authorization) that is widely used worldwide and is currently available in version 2.0.
OAuth 2.0 is currently a popular practice, and it is the first to be used by Google, Yahoo, Microsoft, Facebook, and more. It was labeled as 2.0 because there was initially a 1.0 protocol, but the 1.0 protocol was made too complicated to be easy to use, so it was not popularized. 2.0 is a new design, the protocol is simple and clear, but it is not compatible with 1.0, it can be said that there is no relationship with 1.0.
So here is not to elaborate, first to see how to install it.
Installation
Install Passport
1. Execute the following command in your Shell
Composer require Laravel/passport
If you are using the Laravel version below 5.5, you need to manually add the following code to the config/app.php file providers array
Laravel\passport\passportserviceprovider::class,
2. Run the migration file
Execute the following command in your Shell
PHP Artisan Migrate
The Passport service provider uses the framework to register its own migration directory, so after registering the service you can run PHP artisan migrate directly to generate the required data tables for the passport
3. Generate the Encryption key
Execute the following command in your Shell
PHP Artisan Passport:install
This command creates the encryption key that is required to generate the secure access token, and this command also creates the personal access client and password authorization that is used to generate the access token.
4. Add Trait
Add Laravelpassporthasapitokens Trait to the Appuser model
<?phpnamespace app;use laravel\passport\hasapitokens;use illuminate\notifications\notifiable;use Illuminate\ Foundation\auth\user as Authenticatable;class User extends authenticatable{use Hasapitokens, notifiable;}
5. Registering a route
The function is called in the boot method of Authserviceprovider Passport::routes
.
Class Authserviceprovider extends serviceprovider{public Function boot () { $this->registerpolicies (); Passport::routes (); }}
If your program requires OAuth authentication instead of multi-platform authentication in both front-and back-end, then you can pass an anonymous function in the routers () method to customize the route that you need to register, and here I am the authentication form of the front-end separation, So I just need to provide AUTH authentication for my front-end client, so I only registered the route to get token, and I've also customized the prefix name for it.
Passport::routes (function (Routeregistrar $router) {$router->foraccesstokens ();},[' prefix ' = ' api/oauth ']);
6. Change the gatekeeper driver
Change the driver option of the API for Guards in profile config/auth.php to Passport. This adjustment will allow your application to use Passport Tokenguard to handle requests to validate incoming APIs
' Guards ' + [' web ' = [' driver ' + ' session ', ' provider ' and ' users ',], ' API ' = [ ' Driver ' = > ' passport ', ' provider ' and ' users ',],
Now that the Passport has been installed, the rest of the documentation says the front end, because I only need to use it to do Auth authentication, do not need to implement the full OAuth function, so we can completely do not use the front-end page.
Use
For the API to return the data conveniently, I encapsulated several functions
function respond ($status, $respond) {return response ()->json ([' status ' = = $status, is_string ($respond)? ' Message ': ' data ' = $respond]);} function succeed ($respond = ' Request success! ') {return respond (true, $respond);} Function failed ($respond = ' Request failed! ') {return respond (false, $respond);}
The Respond function can do a basic return, and succeed and failed are again encapsulated on the respond function to return the request success and request failure data.
Then we need to use a layer of proxies.
Let's start with the reason for using a proxy, the Passport-certified process is a dependent application with the main application
Generated Client Token and user-entered account password to request the main app's Passport token route to obtain access token (access token) and refresh token (refresh token), and then bring the obtained access token You can access the routes under the Auth:api. However, we do not have a subordinate application, is a front-end separation from the frontend to request this token, if from the front end to pull this access token will need to write Client token to die in the front, this is very unreasonable, so we can write an agent in the internal, by the application itself with The Client token goes to the request itself to get access token, so there may be a bit of a detour, presumably the request process is like this.
1. Front end With user-entered account password Request server
2. The server takes the account and password from the front end and adds client_id and Client_token to it, then requests its own Passport-certified route with these parameters, then returns the authenticated Access token and Refresh token
Here is the code implementation, I created a new proxyhelpers under the Apphttpcontrollerstraits Trait, of course, this function is my business logic according to my own encapsulation, if not suitable for your business logic you can adjust yourself.
<?phpnamespace App\http\controllers\traits;use Guzzlehttp\client;use App\exceptions\unauthorizedexception;use Guzzlehttp\exception\requestexception;trait proxyhelpers{Public Function authenticate () { $client = new Client (); try { $url = Request ()->root (). '/api/oauth/token '; $params = array_merge (config (' passport.proxy '), [ ' username ' + request (' email '), ' Password ' = Request (' Password '), ]); $respond = $client->request (' POST ', $url, [' form_params ' = $params]); } catch (Requestexception $exception) { throw new Unauthorizedexception (' request failed, server error '); } if ($respond->getstatuscode ()!== 401) { return Json_decode ($respond->getbody ()->getcontents (), true); } throw new Unauthorizedexception (' Account or password error '); }}
config/passport.php content is as follows
<?phpreturn [' proxy ' + = [ ' grant_type ' + env (' Oauth_grant_type '), ' client_id ' = env (' OAUTH _client_id '), ' client_secret ' = env (' Oauth_client_secret '), ' scope ' = env (' Oauth_scope ', ' * '), ],];
Env file content is as follows
Oauth_grant_type=passwordoauth_client_id=2oauth_client_secret=2hatqjf33sx98hjckdisvwzjrhvyggkhgp8xlg1ooauth_ scope=*
The client token we need to use is the client token with ID 2, so don't make the mistake.
Then we just need to use this Trait in the controller, then call to $this->authenticate()
get the token of successful authentication, if the request fails, you can catch the error throw exception.
Public Function Login (Request $request) { $needs = $this->validate ($request, rules (' login ')); $user = user::where (' email ', $needs [' email '])->first (); if (! $user) { throw new unauthorizedexception (' This user does not exist '); } $tokens = $this->authenticate (); return succeed ([' token ' = $tokens, ' user ' = new Userresource ($user)]);}
The resulting tokens returned in the following format
{"Token_type": "Bearer", "expires_in": 31536000, "Access_token": "Token_str", "Refresh_token": "Token_str"}
After all this, you'll be able to request service from the front end.
Axios.post (' Yourdomain/login ', login_form). Then (resource + = {})
If the request succeeds, then you will get the user's information and access Token,refresh token.
Then you need to add a parameter to your front-end HTTP request Header Authorization
axios.defaults.headers.common[' Authorization ' = token.token_type + ' + token.access_token
Then use middleware Auth:api in the route you need to use for Auth authentication, and it's all done!
Summarize
Articles you may be interested in:
Performance optimizations you might miss in PHP: What's relevant to the generator
Implementation of composer automatic loading in laravel framework
PHP Service-side environment construction graphics and text tutorial