Laravel's 5.3 passport and api routes
The problem with Laravel 5.3 passport is that unlike previous OAuth 2.0 Server for Laravel library offered by lucadegasperi, it has no API to make clients directly. So as if now the client can only be made through the front-end. FYI we wanted to use laravel passport solely for our mobile app so while creating and registering user we would have only EMAIL & Password and in some cases only Facebook UserID for facebook sign-in. So the following approach worked pretty well for our case and might differ for your scenario but may help you in the longer term to play around with laravel passport.
Note: Before following the below its assumed you have enabled Password Grant in your application.
So the way we solved it for our project on laravel 5.3 is as follows:
in the oauth_clients convert the id field into a normal field i.e. remove it as being primary key and make the data type as varchar so that we can store email address as client_ids as they are also unique for your system. Incase of Facebook login we store Facebook user IDs here in this column which again will be unique for each our client. Also for other tables like: oauth_access_tokens, oauth_auth_codes & oauth_personal_access_clients change client_id to VARCHAR(255) so that it can store email addresses or Facebook User IDs.
Now go to your models and create a model for oauth_clients table so that you can create client programmatically from the code while creating users.
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class OauthClient extends Model
{
protected $table = 'oauth_clients';
}Then in your api.php route file add the following route:
Route::post('/register-user', function (Request $request) {
$name = $request->input('name');
$email = $request->input('email'),
$password = $request->input('password'),
// save new user
$user = \App\User::create([
'name' => $name,
'email' => $email,
'password' => bcrypt($password),
]);
// create oauth client
$oauth_client = \App\OauthClient::create([
'user_id' => $user->id,
'id' => $email,
'name' => $name,
'secret' => base64_encode(hash_hmac('sha256',$password, 'secret', true)),
'password_client' => 1,
'personal_access_client' => 0,
'redirect' => '',
'revoked' => 0,
]);
return [
'message' => 'user successfully created.'
];
});
In the above code snippet, you have to note that to generate the oauth_client secret you have to use some strong formula of encryption that you feel comfortable using it with your application. Also, use the same technique to generate the secret key on your mobile app for the respective client/user.
Now you can use the standard POST API offered by laravel passport to request access token through password grant using "oauth/token" using the following parameters:
grant_type : 'password'
client_id : '<email with which the user is registered>'
client_secret : '<generate the client secret from the mobile app>'
username : '<email with which the user is registered>'
password : '<password entered by the user>'
scope : '<leave empty as default>'The above will give you a response, if everything is correct, similar to :
{
"token_type": "Bearer",
"expires_in": 3155673600,
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6IjMwZmM0MDk1NWY5YjUwNDViOTUzNDlmZjc2M2ExNDUxOTAxZjc5YTA5YjE4OWM1MjEzOTJlZmNiMDgwOWQzMzQwM2ExZWI4ZmMyODQ1MTE3In0.eyJhdWQiOiJzaHVqYWhtQGdtYWlsLmNvbSIsImp0aSI6IjMwZmM0MDk1NWY5YjUwNDViOTUzNDlmZjc2M2ExNDUxOTAxZjc5YTA5YjE4OWM1MjEzOTJlZmNiMDgwOWQzMzQwM2ExZWI4ZmMyODQ1MTE3IiwiaWF0IjoxNDc4MTQ1NjMyLCJuYmYiOjE0NzgxNDU2MzIsImV4cCI6NDYzMzgxOTIzMiwic3ViIjoiMSIsInNjb3BlcyI6W119.dj3g9b2AdPCK-im5uab-01SP71S7AR96R0FQTKKoaZV7M5ID1pSXDlmZw96o5Bd_Xsy0nUqFsPNRQsLvYaOuHZsP8v9mOVirBXLIBvPcBc6lDRdNXvRidNqeh4JHhJu9a5VzNlJPm3joBYSco4wYzNHs2BPSxXuuD3o63nKRHhuUHB-HwjVxj2GDwzEYXdZmf2ZXOGRJ99DlWGDvWx8xQgMQtd1E9Xk_Rs6Iu8tycjBpKBaC24AKxMI6T8DpelnFmUbMcz-pRsgCWCF_hxv6FpXav3jr1CLhhT58_udBvXjQAXEbtHeB7W_oaMcaqezHdAeOWDcnqREZHsnXHtKt0JpymcTWBkS2cg7sJzy6P9mOGgQ8B4gb8wt44_kHTeWnokk4yPFRZojkHLVZb8YL6hZxLlzgV1jCHUxXoHNe1VKlHArdlV8LAts9pqARZkyBRfwQ8oiTL-2m16FQ_qGg-9vI0Suv7d6_W126afI3LxqDBi8AyqpQzZX1FWmuJLV0QiNM0nzTyokzz7w1ilJP2PxIeUzMRlVaJyA395zq2HjbFEenCkd7bAmTGrgEkyWM6XEq1P7qIC_Ne_pLNAV6DLXUpg9bUWEHhHPXIDYKHS-c3N9fPDt8UVvGI8n0rPMieTN92NsYZ_6OqLNpcm6TrhMNZ9eg5EC0IPySrrv62jE",
"refresh_token": "BbwRuDnVfm7tRQk7qSYByFbQKK+shYPDinYA9+q5c/ovIE1xETyWitvq6PU8AHnI5FWb06Nl2BVoBwCHCUmFaeRXQQgYY/i5vIDEQ/TJYFLVPRHDc7CKILF0kMakWKDk7wJdl5J6k5mN38th4pAAZOubiRoZ+2npLC7OSZd5Mq8LCBayzqtyy/QA5MY9ywCgb1PErzrGQhzB3mNhKj7U51ZnYT3nS5nCH7iJkCjaKvd/Hwsx2M6pXnpY45xlDVeTOjZxxaOF/e0+VT2FP2+TZMDRfrSMLBEkpbyX0M/VxunriRJPXTUvl3PW0sVOEa3J7+fbce0XWAKz7PNs3+hcdzD2Av2VHYF7/bJwcDCO77ky0G4JlHjqC0HnnGP2UWI5qR+tCSBga7+M1P3ESjcTCV6G6H+7f8SOSv9FECcJ8J5WUrU+EHrZ95bDtPc9scE4P3OEQaYchlC9GHk2ZoGo5oMJI6YACuRfbGQJNBjdjxvLIrAMrB6DNGDMbH6UZodkpZgQjGVuoCWgFEfLqegHbp34CjwL5ZFJGohV+E87KxedXE6aEseywyjmGLGZwAekjsjNwuxqD2QMb05sg9VkiUPMsvn45K9iCLS5clEKOTwkd+JuWw2IU80pA24aXN64RvOJX5VKMN6CPluJVLdjHeFL55SB7nlDjp15WhoMU1A="
}
Its only a temporary solution till laravel supports an external API for applications which only has a mobile as the only possible interface for creating oAuth clients and user.
Hope it helps you!
Cheers.
404 - Not Found Passport Api Route That Exists Laravel 8
I was stuck with this for a week. There can be many things that can cause this issue.
1 - Make sure you installed passport correctly.
It appears laravel 8 comes with "Sanctum" pre-installed so there is a likelihood that you will make mistakes with some of passport's installation requirements. Go through the installation again. Passport Installation Look at the example I have below of a possible mistake.
Look inside your User Model and make sure you have "use Laravel\Passport\HasApiTokens;" NOT "use Laravel\Sanctum\HasApiTokens;"
2- If you are not using "Sanctum", you are better off removing it from your project
Go to the search on the left side bar of VSCODE and search for "Sanctum".
Click on "composer.json", go to the require section and carefully remove "Sanctum" requirement. Also check all the other search results to make sure you are not using Sanctum in a place where it should be passport. Remove them if need be.
3- In your terminal, type the command below to Update composer and generate a new lock file
composer update
4- If you moved your User model to a new folder (eg: version1) like I did, go to "config/auth.php" and update the providers for user with the correct path of the User model
5- Make sure in the api section of app/Http/Kernel.php, "\Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class" is commented out.
6- Go to terminal, clear your routes from cache, list them with the commands below and check if the route you listed in api.php shows there.
php artisan route:clear
php artisan route:list
If "php artisan route:list" shows an error, then make sure your route is declared correctly. For clarity sake, make sure you use the full path of your controller and crosscheck your UserController to make sure of the function matches(they are case sensitive) exactly with what is in your api.php file. Also, if you are using a controller in your route, declare it above "use App\Http\Controllers\version1\UserController;" like shown in the image below. Repeat "php artisan route:clear" and "php artisan route:list" in terminal to make sure there is no error and your route is listed.
7- Make sure the url you are calling in postman is correct and the method is also correct.
Remember, if your url in api.php is "/v1/user/register" then in postman, you should have "api/v1/user/register" in postman. That means your final url will be "http://myvhostname.local/api/v1/user/register"
Remember, if you declared your route in api.php to be a "get" then make sure it is a "get" in postman. If it's a post, make sure they match in postman too.
Go to the "headers" section of postman and include "Accept=application/json" as shown below
8- If you still have a 404-Not Found, open your vhost file "httpd-vhosts.conf" in "Applications >> XAMPP >> xamppfiles >> etc >> extra" and make sure your vhost is declared correctly as below. Improper declaration can make web routes work but api routes won't. Pay close to "Allowoverride All".
Your routes should work now. If this worked for you, an upvote would be appreciated
Related Topics
MySQL Alter Table Add Field Before or After a Field Already Present
How Do Check If a PHP Session Is Empty
Can't Make Laravel 4 to Work on Localhost
How to Set Current Page "Active" in PHP
"Class Xxx Is Not a Valid Entity or Mapped Super Class" After Moving the Class in the Filesystem
What Security Problems Could Come from Exposing PHPinfo() to End Users
Get "Content-Type" Header of Request in PHP
Send Checkbox Value in PHP Form
Secure User Image Upload Capabilities in PHP
Escaping Column Names in Pdo Statements
PHP How to Get the Base Domain/Url
What Is 22527 in Error_Reporting 22527 of PHPinfo
How to Remove Empty Paragraph Tags from String
How to Send Cookies with File_Get_Contents