Laravel 5.3 Passport JWT Authentication - laravel-5.3

Earlier when I was using laravel 5.2, i used a third party package https://github.com/tymondesigns/jwt-auth/ for making JWT based authentication. Where we just had to pass the username and password to get a token.
Now in laravel 5.3 with the introduction of passport I want to make a JWT based authentication but passport requires me to specify the client_id and client_secret along with the username and password. which was not there in tymondesigns/jwt-auth.
If I make a request without the client_id then it throws an error http://pix.toile-libre.org/upload/original/1482908288.png but when I pass the client_id and client_secret then it works fine http://pix.toile-libre.org/upload/original/1482908143.png
How can I make a JWT request in laravel 5.3 and passport with just the username and password and without specifying client_id and client_secret.

So, finally I am answering my own question. Hopefully this will help someone facing the similar problem.
JWT authentication can be done using Laravel 5.3 passport, just follow the following steps:
Install Passport normally as described in this link https://laravel.com/docs/master/passport#installation
OR follow these steps:
composer require laravel/passport
add Laravel\Passport\PassportServiceProvider::class, to your app providers
php artisan migrate
php artisan passport:install
Add HasApiTokens trait to your user model
Passport::routes(); in AppServiceProvider
Configure api driver to passport
Once done, create a UserController and add the following methods in it:
public function auth(Request $request)
{
$params = $request->only('email', 'password');
$username = $params['email'];
$password = $params['password'];
if(\Auth::attempt(['email' => $username, 'password' => $password])){
return \Auth::user()->createToken('my_user', []);
}
return response()->json(['error' => 'Invalid username or Password']);
}
public function index(Request $request)
{
return $request->user();
}
In routes/api.php, add the following routes:
Route::post('auth', 'UserController#auth');
Route::group(['middleware' => 'auth:api'], function(){
Route::resource('user', 'UserController#index');
});
Now make a POST request to http://localhost:8000/auth with the email address and password as shown in the screenshot (http://pix.toile-libre.org/upload/original/1483094937.png) This will get you the accessToken, you can use this token to make other requests in your application with the Authorization header and Bearer XXX where xxx is the accessToken you received from /api/auth endpoint.
Now, make a GET request to /api/user with the Authorization header and the token value, this will return the authenticated user's details.
(eg: http://pix.toile-libre.org/upload/original/1483095018.png)
I have also posted these steps on my blog at http://chatterjee.pw/larvel-passport-jwt-authentication/
I hope this helps!

If you are not interested in OAuth and Client thing, you probably want to use pure JWT authentication, if so, you can check out this package:
https://github.com/miladrahimi/larajwt
It declares a new authentication driver named "jwt" to protect your authenticated routes, it provides a service to generate jwt from your users, and some other tools like logout, user model caching, filters for checking extra properties of users and so on.

$request->user(); was not working for me because the middleware is configured to web, which I also need + api. The docs are not clear about how to control for both scenarios.
I was able to get users details with get Auth Bearer + token, and on Laravel:
use Illuminate\Support\Facades\Auth;
Route::get('/user', function() {
return Auth::guard('api')->user();
});

You got this all mixed up. Passport is ideal for Facebook-like applications where you want your users’ clients to securely authenticate to your API.
If all you are doing is building a rest API for example a health and fitness app, using the Tyson JWT package suffices. This is because you don’t have the middleman.

Related

Node WPAPI REST with JWT Authentication combined?

I have a Wordpress REST-API Backend with a UI5 JavaScript Frontend which loads some Post-Data to list them.
I want to protect this by a simple Login-Form in the Frontend.
To fetch and create the posts i use Node-WPAPI with basic authencation, like this:
this._oWp = new WPAPI({
endpoint: 'http://<domain>/wordpress/wp-json',
username: '<user>',
password: '<pass>'
});
But this approach dont fit my needs, because creating this WPAPI instance is even possible with a wrog password. Thus i would have to send a request to protected route first to know if my password was correct.
To directly know if my login was correct my idea was to firstly get a Token via "JWT Authentication for WP-API" and this actually works and i get the token.
But doing this my WPAPI Endpoints resulting with error "jwt_auth_bad_auth_header, "Authorization header malformed."
Is there a way to use WPAPI together with JWT Auth? Or how could a Login be authenticated by WPAPI Instance and get directly notified when the login credential were wrong?
I managed this with the WPAPI-Only-Approach, so proving that the user entered the right credentials by simply sending a request to .users().me() which needs a correct authentification. Otherwise you get an "Not authenticated" Error.
let oWp = new WPAPI({
endpoint: <your_endpoint>,
username: this._oAuth.getProperty("/Username"),
password: this._oAuth.getProperty("/Password"),
});
oWp.users().me()
.then( user => {
this._oWp.setData(oWp);
this._oRouter.navTo('home');
}).catch( error => {
console.log(error);
});

ADFS 4.0 (2016) OpenID Connect userinfo endpoint returns 401 when provided with access token

Any ideas why this is. I have configured a Server Application and a Web API and an ID Token, Access Token & Refresh token is issued. However calling the userinfo endpoint return a 401 with the following header message:
WWW-Authenticate →Bearer error="invalid_token", error_description="MSIS9920: Received invalid UserInfo request. The access token in request is not valid."
The access token is valid according to http://jwt.io
eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6IjVVbEw5a1JocDJNLUVzTDlBRDJOQ055aHZtdyJ9.eyJhdWQiOiJ1cm46bWljcm9zb2Z0OnVzZXJpbmZvIiwiaXNzIjoiaHR0cDovL3Rlc3Rsb2dpbi51bm9wcy5vcmcvYWRmcy9zZXJ2aWNlcy90cnVzdCIsImlhdCI6MTQ4NjYyOTUxOSwiZXhwIjoxNDg2NjMzMTE5LCJhcHB0eXBlIjoiQ29uZmlkZW50aWFsIiwiYXBwaWQiOiJrbnVkIiwiYXV0aG1ldGhvZCI6InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphYzpjbGFzc2VzOlBhc3N3b3JkUHJvdGVjdGVkVHJhbnNwb3J0IiwiYXV0aF90aW1lIjoiMjAxNy0wMi0wOVQwODozMjo1Ny4xNDZaIiwidmVyIjoiMS4wIiwic2NwIjoib3BlbmlkIiwic3ViIjoiM2krUGlyRncwSVlkdDVzTVNKQlpKbjVOTXZVWXZVdyt2WHI2Ujd1N0dBZz0ifQ.ajKtSk0xQE1crJkIA-lMLBZj2DtYE6xQo-Stmevh4pOGX17GEePbAFP-g6qPUwtGT_whVj74wRpSlyTBscp2JDsp_CW2E6BsTUI810S6jYRVjkYGxL1QcL1KoKJ8wyYKcxsCeOY2IUKNPnJOxV53Rs8E9EvJgjcsjTJHQw5Z_zC43dsTfCZvVfGrwJ3nn6BGxhIE_bEXvrWdgmg49V7-KK2kVDbDwJGr1iLpqU88-bkHdjGCIuc8XKX5pobWWlcyBmR_dpACM6Tu-d8jYJ_8mbof-eZrqn8YS61rgvRAhAAONyDklWcPgiYnhcMQVHZoCME-rVTjI6LDDY2czhL0rg
This question is asked long time ago but let me share my experience.
if you want to execute ADFS 4.0 userInfo endpoint(win server 2016) in a hope to get User profile but what i experienced is it return only Sub attribute
ex:
{
"sub": "MpR57wSIQz1kiR2uUMrkCQadbgDoztWmMV863Dugdso="
}
for anyone to try UserInfo endpoint you need to modify your application group, add api with Identitfier https://adfs.example.com/adfs/userinfo & at Client permission tab tick openId.
for execution of userinfo
Ex:
curl -X GET \
https://adfs.example.com/adfs/userinfo \
-H 'Authorization: Bearer ACCESS_TOKEN
Note: In your Acquire Accesstoken code you need to pass your resource = urn:microsoft:userinfo
The ADFS userinfo endpoint always returns the subject claim as
specified in the OpenID standards. AD FS does not provide additional
claims requested via the UserInfo endpoint. If you need additional
claims in ID token, refer to Custom ID Tokens in AD FS.
I've only done this once so I don't have much suggestions to make yet. So I cant make any suggested unless there is more detail.
You should try and get more evidence from the AD FS side. Enable debug logs using
wevtutil sl "ad fs tracing/debug" /l:5 /e:true
Do the repro and then disable logs as follows.
wevtutil sl "ad fs tracing/debug" /e:false
Then export the logs to view using
wevtutil epl "ad fs tracing/debug" c:\temp\userinfoerr.evtx
Open that event log in event viewer and have look and see what other errors are reported around validating the JWT.

Laravel Passport - Grant Type Not Supported

I have installed Laravel Passport per the documentation and I have modified all areas of my code that is required.
I am working on setting up Password Grant Tokens so that users will be able to get an API token when logging in with their username and password for the site. I am hitting an issue though when it comes to the grant_type.
For some reason Laravel is complaining about an invalid grant type.
{
"error": "unsupported_grant_type",
"message": "The authorization grant type is not supported by the authorization server.",
"hint": "Check the `grant_type` parameter"
}
These are the fields that I am posting to /oauth/token
client_id = 4
client_secret = SMiYE7XqDNtXKQnmkYmFnXxfAaV83vRhnJ9zwCtZ
username = jcrawford#domain.com
password = **************
grant_type = password
scope = *
I have run php artisan passport:install and I have also tried running php artisan passport:client --password
Both commands worked and both created the client and secrets, however, I cannot seem to get past the error about the grant_type.
Any suggestions on what I should look at to get this solved so that Password Grant Tokens will work for me?
It appears that you must send the parameters as form data and not in the headers like I was doing... Rookie Mistake!
I'm using Postman and I have put all parameters in Params. Postman shows the following response
{
"error": "unsupported_grant_type",
"message": "The authorization grant type is not supported by the authorization server.",
"hint": "Check the `grant_type` parameter"
}
Now I put all parameters in Body and then press the Send button, It's working well.
For me the problem was that i wasnt using Request $request, i was using RegisterRequest $request which i had created.
Initial URL
https://restfulapi.test/oauth/authorize?client_id=3&redirect_url=http://restfulapi.test?response_type=code
Solution
https://restfulapi.test/oauth/authorize?client_id=3&redirect_url=http://restfulapi.test&response_type=code
I had to replace the question mark before response_type with the &
Reading the Laravel documentation saved me a lot of stress. The oauth\token is used to retrieve token using the grant type specified, the route will return a JSON response containing access_token, refresh_token, and expires_in attributes. The expires_in attribute contains the number of seconds until the access token expires (ref) You are meant to
Install passport
Publish the service providers and migrations and migrate.
Setup a route for login/register to create an account and login.
In your User model, add HasApiTokens from use Laravel\Passport\HasApiTokens;
In your response in your login method, add the token as part of the response.
Test your response on postman

Integrate API authentication to WordPress

I have a website where I have to authenticate the users registered in another system (in this case the Kayako support system).
I think I have to use the APIs to resolve this problem, but I don't really know how to get started.
Can someone please help me solve this problem? How can I send the data required for the authentication and how do I manage the response I get from Kayako.
Figure out how the API of the Kayako system looks like. In WordPress you can do something similar like this in order to authenticate the users:
// this action is executed just before the invocation of the WordPress authentication process
add_action('wp_authenticate','checkTheUserAuthentication');
function checkTheUserAuthentication() {
$username=$_POST['log'];
$password=$_POST['pwd'];
// try to log into the external service or database with username and password
$ext_auth = try2AuthenticateExternalService($username,$password);
// if external authentication was successful
if($ext_auth) {
// find a way to get the user id
$user_id = username_exists($username);
// userdata will contain all information about the user
$userdata = get_userdata($user_id);
$user = set_current_user($user_id,$username);
// this will actually make the user authenticated as soon as the cookie is in the browser
wp_set_auth_cookie($user_id);
// the wp_login action is used by a lot of plugins, just decide if you need it
do_action('wp_login',$userdata->ID);
// you can redirect the authenticated user to the "logged-in-page", define('MY_PROFILE_PAGE',1); f.e. first
header("Location:".get_page_link(MY_PROFILE_PAGE));
}
}
The try2AuthenticateExternalService() method should contain some curl-request (or similar) to the remote service.

Integrate HWIOAuthBundle and Google Api Client - How to set correct token

I have symfony2 page where i use HWIOAuthBundle integrated with FOSUserBundle. HWIOAuth using my own user provider which extend through base FOSUBUserProvider (HWI\Bundle\OAuthBundle\Security\Core\User\FOSUBUserProvider). With this class i am able to retrieve information about AccessToken. My question is - how to set correct access token in Google Api Client, example code:
$client = new \Google_Client();
$client->setApplicationName("XXX");
$client->setClientId($this->container->getParameter('google_client_id'));
$client->setClientSecret($this->container->getParameter('google_client_secret'));
var_dump($user->getGoogleAccessToken()); // 83 characters string with google access token
$client->setAccessToken($user->getGoogleAccessToken());
Last line throws error "Could not json decode the token", when i trying to set json_encode then it throws "Invalid token format" error
If you are using the v2 of Google PHP SDK, you should do the following
$client->setAccessToken([
'access_token' => $accessToken,
'expires_in' => $expiresIn,
]);
Regards

Resources