i am using https://github.com/lucadegasperi/oauth2-server-laravel in laravel framework for creating Api's. i configured all setup. when i make a call to get token it shows
{ "error": "invalid_request", "error_description": "The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed. Check the "grant_type" parameter." }
My grant type is -
'grant_types' => [ 'client_credentials' => [ 'class' => '\League\OAuth2\Server\Grant\ClientCredentialsGrant', 'access_token_ttl' => 3600 ] ],
token is -
'token_type' => 'League\OAuth2\Server\TokenType\Bearer', i need sample url for access my api.. whether i need to pass access token where can i get access token.
i dont find any tut about geting access token and use them correctly. please help me on this..
thanks in advance.
I am using the same package with laravel 5. There is this tutorial that explains it well.
After you publish the package settings, run migrations and add some test data in the oauth_clients and your users tables. Specifically you add client_id and client_secret in the oauth_clients table. Also create a user with username and password in your users table. Finally using POSTMAN chrome extension provide the following data to a POST route to get your access_token.
grant_type as password,
client_id as what you added above,
client_secret as what you just created above,
username your test username,
password your test user password,
You should get correct access_token from POSTMAN.
I think what you need is to include your client_id and secret_id parameters
that you got from github when you created your OAuth application. I use socialite and I had used the following information inside config/services.php
'github' => [
'client_id' => 'CLIENT_ID',
'client_secret' => 'CLIENT_SECRET',
'redirect' => 'REDIRECT_RUL'
]
Of course that's a temporary solution, if you use laravel 5 I suggest you to save this information inside .env files as they are more secure.
More about .env more about socialite
Related
I am working on Laravel 7 and for social login I am using Socialite package.
I am following this article for reference and did exactly the same but I am getting
an unauthorized response with a message - "Bad Credentials". I have also tried resetting the secret key.
This is my Github settings
Thanks for the response.
Aside from making sure that your client_id and client_secret are set correctly, you also need to ensure that your redirect value in your config/services.php:
'github' => [
'client_id' => env('GITHUB_CLIENT_ID'),
'client_secret' => env('GITHUB_CLIENT_SECRET'),
'redirect' => 'http://yourapp.test/login/github/callback'
],
Is identical to what you set under your Github app:
I am trying to login with google using socialite , my facebook login works fine so the problem in my google app, any help!!!
'google' => [
'client_id' => 'app-key',
'client_secret' => 'app-secret',
'redirect' => 'http://www.shoptizer.com/callback/google',
],
Also one more point to remember that Socialite also gives uri_mismatch_error even when your redirects are correctly defined in google console but you dynamically changed the redirectUrl through
return Socialite::with('google')->redirectUrl($redirect_url)->redirect();
So plz take care that you should also need to define while receiving the response
Socialite::driver('google')->redirectUrl($redirect_url)->stateless()->user();
where $redirect_url is your custom redirect url.
After google redirects you to correct place, but even then Socialite checks it at its end.
I found this link https://blog.damirmiladinov.com/laravel/laravel-5.2-socialite-google-login.html
From this tutorial:
Occasionally it happens that google require some time to apply client configuration If you get an error message redirect_uri_missmatch wait couple of minutes and it should work normally.
Also change the redirect uri by:
'google' => [
'client_id' => 'app-key',
'client_secret' => 'app-secret',
'redirect' => 'https://www.shoptizer.com/callback/google',
],
If your app is provided by https you must match your http scheme on google api and on your redirect callback.
The problem is in the default url, you must change it on two occasions: before the redirect and before getting the user data.
Do not do this:
return Socialite::driver('google')->redirectUrl($yourredirecturl)->redirect();
Do it:
config()->set('services.google.redirect', $yourredirecturl);
return Socialite::driver('google')->redirect();
And when accessing user data, do this:
config()->set('services.google.redirect', $yourredirecturl);
$user = Socialite::driver('google')->user();
I am using:
Postman/Insomnia for REST checking
Laravel 5.6 with Laravel Passport
Vagrant (Apache 2, PHP 7.2)
Made all checklist described on Laravel Docs for Laravel Passport and after certain steps I receive HTTP 401 for my valid OAuth access token.
Requested by /oauth/token/ the new access token with client_id and client_secret.
Used received access token to authorize my simple Laravel REST test controller with included Oauth api middleware.
The end is one: 401 unauthorized :(
So, here is some of my configurations:
Apache
api route
Kernel.php
PassportServiceProvider.php
AuthServiceProvider.php
I had a very similar issue too:
The difference between your codes and mine:
In the routes/api.php, i used only auth:api.
I didn't create PassportServiceProvider.php in the app folder.
In the Kernel.php mine is client not client_credentials.
I used client_credentials as grant_type in the POST request call.
In the result I always got 401.
Until I created a user using Password Grant Client:
php artisan passport:client --password
And changed client_credentials to password in the POST request call:
$http = new GuzzleHttp\Client;
$response = $http->post('http://your-app.com/oauth/token', [
'form_params' => [
'grant_type' => 'password',
'client_id' => 'client-id',
'client_secret' => 'client-secret',
'username' => 'taylor#laravel.com',
'password' => 'my-password',
'scope' => '',
],
]);
$access_token = json_decode((string) $response->getBody(), true)['access_token'];
Put the access token returned in the Bearer of the headers, and it works.
And also you can get the current user using $request->user();
If you are using client_credentials as grant_type, it's going through the client middleware, so in the middleware auth:api needs to be removed.
This is because Apache does not, by default, pass authorization headers to PHP. You need to edit your Apache site configuration to add a line to Deskpro's directive. Note that this configuration must be added directly to Apache's configuration (e.g., adding it to htaccess will not work
<VirtualHost>
# ...
SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1
# ...
I have read below article and it is just awesome. Everything from that article is clear however I have one major doubt.
https://stormpath.com/blog/the-ultimate-guide-to-mobile-api-security
The article author said that in 'OAuth2 password grant' while logging into the mobile application, just need to send email and password in order to get the access token from the API server, but I have read at many places that you also need to send client_id and client_secret in that request. I'm going to build my API using Laravel:
https://laravel.com/docs/master/passport#password-grant-tokens
Here you can see it forces me to send client_id and client_secret in that request.
I'm really confused about this. If I have to send client_id and client_secret in that request, first I need to get it from the authorization server by creating a client on it. So at which event, I should create that client? When a user tries to log in from the mobile application? I just need to know the exact flow.
Any help would be appreciated.
Thanks
A client gets created for the developers who need to integrate with the OAuth2 server. It has nothing to do with the specific users' login flow.
ex. I want to integrate with Facebook login; I create a client on Facebook and incorporate that into my service, its Facebooks way of knowing who my service is.
So, a user logs in through your application; your application then sends that username and password to a backend server. The backend server then adds the client_id and secret so the OAuth server can verify the authenticity of the request.
So in your case, a user logs into your mobile application, you send that login request (username and password, with SSL) to your backend server. Your backend server then forwards that request to the OAuth2 service looking like the request below.
'form_params' => [
'grant_type' => 'password',
'client_id' => 'client-id',
'client_secret' => 'client-secret',
'username' => 'user#email.com',
'password' => 'user-password',
'scope' => '',
],
This directly returns an access_token and a refresh token that you can safely store in your mobile application.
I create the grant client in a migration called ConfigurePassport and set the key i want the app to use. You do not need a client per user.
public function up()
{
/*
* This command will create the encryption keys needed to generate secure access tokens.
* In addition, the command will create "personal access" and "password grant"
* clients which will be used to generate access tokens
*/
Artisan::call( 'passport:install', array('-n' => true) );
// Set Password Grant Client secret to known key
DB::table( 'oauth_clients' )->where( 'password_client', 1 )->update(
['secret' => env( 'GRANT_CLIENT_SECRET', 'dfhsdfhbtg545fdf45yedh5f5blahblah' )]
);
}
The above migration runs the artisan command passport:install as per the documentation to install the client. https://laravel.com/docs/master/passport#password-grant-tokens
Now your mobile app can request a token like so: the unique per user params are username and password.
You can find the client id in the oauth_clients table where password_client is true. It will likely be 2.
$http->post('http://your-app.com/oauth/token', [
'form_params' => [
'grant_type' => 'password',
'client_id' => 2,
'client_secret' => 'dfhsdfhbtg545fdf45yedh5f5blahblah',
'username' => 'taylor#laravel.com',
'password' => 'my-password',
'scope' => '',
],
]);
There are two different concepts:
Client: is the piece of software that's intended to communicate with your server. Usually, you will have 3 main clients which are your iOS, Android and web apps.
User: Which is the end-user that will interact with one of your clients, then the client will be communicating with the Oauth server on behalf.
So you will need to generate a client_id & client_secrete only one time. Then you can use these keys to be the authorized middle-man between your Oauth Server & the end-users.
In the case of Password Grant, The client_key & secrete_key are used to obtain the access_token for every user of each client you have.
Once the client obtains the access_token of a particular user (usually upon logging-in), the client will not need to send the client_key & secrete_key anymore, only the access_token.
However, if that user's access_token has expired, you will have to use those keys to exchange a new access_token with the refresh_token you already received from the login process.
I'm building an app using Angular 2 (no known as 4) as frontend and Laravel 5.4 as API backend. I'm using Laravel's passport password grant feature to authenticate user access to API.
The Frontend is not directly accessing oauth routes. My custom auth controller is talking to oauth/token to get the grant values.
This setup is working perfectly fine in my local environment, but in AWS EC2 it throws 500 internal server error.
I thought it could be related to GuzzleHttp\Client, but it was not. Even if I try to access oauth/token directly from Postman, it still throws 500 internal server error.
private function getPasswordGrant($username, $rawPassword) {
$http = new HttpClient();
$url = url('/') . "/oauth/token";
return $http->post($url, [
"form_params" => [
"grant_type" => "password",
"client_id" => config("auth.oauth_password_grant_client_id"),
"client_secret" => config("auth.oauth_password_grant_client_secret_key"),
"username" => $username,
"password" => $rawPassword,
"scope" => "*",
],
]);
}
This is the function in my custom Auth Controller which requests for password grant after the user being authenticated in another method (login and signup).
Most amazing thing is there's nothing logged in either laravel or apache logs.
Alright, after a lot of struggle and debugging. It turned out to be apache was unable to write into storage/logs/laravel.log and causing this problem. After giving appropriate permissions to storage/ folder everything is working as expected.