How can I get the data from token - jwt

I am trying to get data included in a JWT Token with Angular 6.
I can do the login action, and return the token with Lumen 5.6 - tymondesigns/jwt-auth
But then, when I print it in JS, I get:
iat: 1531073200
iss: "https://api.kz-api.test/auth/login"
jti: "taCmXQoo0jWs4y7t"
nbf: 1531073200
prv: "87e0af1ef9fd15812fdec97153a14e0b047546aa"
sub: 1
I thought I should have the user object in ‘sub’ array as it identifies the subject of the JWT, but I can only find 1….
What’s wrong with my code:
/**
* Authenticate a user and return the token if the provided credentials are correct.
*
* #return mixed
*/
public function authenticate()
{
// Find the user by email
$user = User::where('email', $this->request->input('email'))->first();
if (!$user) {
return response()->json('login.wrong_email', HttpResponse::HTTP_UNAUTHORIZED);
}
$credentials = Input::only('email', 'password');
if (!$token = JWTAuth::attempt($credentials)) {
return response()->json('login.wrong_password', HttpResponse::HTTP_UNAUTHORIZED);
}
return response()->json(compact('token'), HttpResponse::HTTP_ACCEPTED);
}

Related

How to fetch access token from OAuth used in google action for smart home

For my smart home action I used fake auth as shown in codelab- smartwasher application. (For testing purpose ). The app is working fine. I have build my own code to work with my devices(Switches). Now When I am implementing OAuth which uses my own custom OAuth server. I am not able to figure out how to implement it in my code. The OAuth is working as needed when I tested. But I want help in integrating it with google action. I am facing problem fetching access token.
The code is as follows:
exports.fakeauth = functions.https.onRequest((request, response) => {
const responseurl = util.format('%s?code=%s&state=%s',
decodeURIComponent(request.query.redirect_uri), request.query.code,
request.query.state);
console.log('*********'+responseurl);
return response.redirect(responseurl);
});
exports.faketoken = functions.https.onRequest((request, response) => {
const grantType = request.query.grant_type
? request.query.grant_type : request.body.grant_type;
const secondsInDay = 86400; // 60 * 60 * 24
const HTTP_STATUS_OK = 200;
console.log(`Grant type ${grantType}`);
let obj;
if (grantType === 'authorization_code') {
obj = {
token_type: 'bearer',
access_token: '123access',
refresh_token: '123refresh',
expires_in: secondsInDay,
};
} else if (grantType === 'refresh_token') {
obj = {
token_type: 'bearer',
access_token: '123access',
expires_in: secondsInDay,
};
}
response.status(HTTP_STATUS_OK)
.json(obj);
console.log('********** TOKEN **********',response);
});
The above code executes with fake auth.
Why is is not executing when I am implmenting custom OAuth?
Do I need to do any changes for clienID and secret in firebase?
How to fetch access token returned by OAuth?
Kindly help. I am new to node.js.
The authorization code that will come back in requests will be in the header, as an Authorization field. Here's a way to pull it out using Node.js.
function getToken(headers) {
// Authorization: "Bearer 123ABC"
return headers.authorization.substr(7);
}

Socialite redirect the user after successful facebook registeration

I'm using Laravel 5.5 and using Socialite to register users via facebook, this is my handleProviderCallback
public function handleProviderCallback(Request $request)
{
$state = $request->get('state');
$request->session()->put('state',$state);
session()->regenerate();
$user = Socialite::driver('facebook')->user();
$userInsert = new User();
$userInsert->name = $user->getName();
$userInsert->email = $user->getEmail();
$userInsert->password = bcrypt('password');
$userInsert->save();
return redirect()->guest('admin/dashboard');
}
the user is inserted successfully in the database but i can't redirect him to "admin/dashboard" how to do it.
Try to force the user to login before redirect him/her to dashboard:
Insert this:
\Auth::login($userInsert, true);
Before:
return redirect()->guest('admin/dashboard');

why don't work Facebook Login after march of 2017? [duplicate]

Because it's due date for graph api 2.2, I'm trying fix my graph api using v2.3
But I discover most api request response nothing when I use 2.3, but I can not found any update for this in the upgrade document. For example:
https://graph.facebook.com/v2.3/{$user_id}?date_format=U&fields=albums.order(reverse_chronological).limit(100).offset(0){id,count,name,created_time}
will return nothing if I use 2.3.
And I can't get user's birthday when I call:
https://graph.facebook.com/v2.3/{$user_id}
It's only return name and live location.
But in v2.2, it include birthday profile.
I use facebook SDK 3.2.2 because my php version is 5.3.
Is there any update that I don't know? Thanks.
I have found the problem myself. It's because the SDK 3.2.2. For facebook update (from the Changelog for API version 2.3):
[Oauth Access Token] Format - The response format of https://www.facebook.com/v2.3/oauth/access_token returned when you exchange a code for an access_token now return valid JSON instead of being URL encoded. The new format of this response is {"access_token": {TOKEN}, "token_type":{TYPE}, "expires_in":{TIME}}. We made this update to be compliant with section 5.1 of RFC 6749.
But SDK is recognize the response as an array(in the getAccessTokenFromCode function):
$response_params = array();
parse_str($access_token_response, $response_params);
if (!isset($response_params['access_token'])) {
return false;
}
return $response_params['access_token'];
This will not get user access token correctly, and you can't get user's data. So you should update this function to parse data as json:
$response = json_decode($access_token_response);
if (!isset($response->access_token)) {
return false;
}
return $response->access_token;
Then all of the function will work as usual.
Additionally, you must make similar changes to setExtendedAccessToken(). Otherwise, your app won't be able to extend access tokens. The code below demonstrates how to upgrade the function.
/**
* Extend an access token, while removing the short-lived token that might
* have been generated via client-side flow. Thanks to http://bit.ly/ b0Pt0H
* for the workaround.
*/
public function setExtendedAccessToken() {
try {
// need to circumvent json_decode by calling _oauthRequest
// directly, since response isn't JSON format.
$access_token_response = $this->_oauthRequest(
$this->getUrl('graph', '/oauth/access_token'),
$params = array(
'client_id' => $this->getAppId(),
'client_secret' => $this->getAppSecret(),
'grant_type' => 'fb_exchange_token',
'fb_exchange_token' => $this->getAccessToken(),
)
);
}
catch (FacebookApiException $e) {
// most likely that user very recently revoked authorization.
// In any event, we don't have an access token, so say so.
return false;
}
if (empty($access_token_response)) {
return false;
}
//Version 2.2 and down (Deprecated). For more info, see http://stackoverflow.com/a/43016312/114558
// $response_params = array();
// parse_str($access_token_response, $response_params);
//
// if (!isset($response_params['access_token'])) {
// return false;
// }
//
// $this->destroySession();
//
// $this->setPersistentData(
// 'access_token', $response_params['access_token']
// );
//Version 2.3 and up.
$response = json_decode($access_token_response);
if (!isset($response->access_token)) {
return false;
}
$this->destroySession();
$this->setPersistentData(
'access_token', $response->access_token
);
}

Laravel Passport and Ionic2 Facebook-Login

I am developing a mobile app which should do API calls to an own laravel backend.
Frontend: Ionic 2 + Angular2
Backend: Laravel 5.3 + Laraval Passport + MySQL
At the user can log in with password grant (username + password).
Now I want to offer a login via Facebook.
I've implemented a Login with Facebook-button in the app. This works fine. I get the profile information from the Facebook API: id, email, name
Now this user (has no email + password combination from our server) should be able to make API calls to our Laravel server and should be linked to user in the users-table of the MySQL-database behind the laravel backend. Users which login with Facebook shouldn't need any username or password to login. Just Facebook.
I want to generate a new user in the database for each facebook user (simply with a column facebook_id). But how to give such users an access_token?
Accepting just the Facebook ID, match this (or create new) user in the database and create an access_token would be very unsecure because Facebook ID is public...
I must say I have same problem couple of weeks ago. Only difference I got was that I have both, ionic2 app and website. Both must support username/password login as social login (google, facebook).
So how did I did that (I will write for facebook, google is slightly different - better):
Prepare your facebook app to accept logins from mobile AND webpage. You will need facebook client_id and client_secret.
Install socialite package for laravel. And set it up to work with facebook ( in app/services.php set facebook ).
Now when you got this you can start coding. You said you already have it working on Ionic2 part. So that means you get token and other data from facebook for user.
What I did is I make request to my api and send this token and user_id. Then on my API side I check if token is valid, login user and issue passport token.
Ionic2 code:
Facebook.login(["public_profile"])
.then(response => {
// login success send response to api and get token (I have auth service class to do that)
this.auth.facebookLogin(response.authResponse).then(
...
);
}, error => {
this.showAlert( this.loginFailedTitle, this.loginFailedText );
});
Now Laravel part. I made SocialController.php and url (POST request) /api/social-login/facebook:
<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Model\SocialLogin;
use App\User;
use Illuminate\Http\Request;
use Socialite;
class SocialController extends Controller
{
public function facebook(Request $request) {
$user = Socialite::driver('facebook')->userFromToken( $request->input('accessToken'));
abort_if($user == null || $user->id != $request->input('userID'),400,'Invalid credentials');
// get existing user or create new (find by facebook_id or create new record)
$user = ....
return $this->issueToken($user);
}
private function issueToken(User $user) {
$userToken = $user->token() ?? $user->createToken('socialLogin');
return [
"token_type" => "Bearer",
"access_token" => $userToken->accessToken
];
}
}
Now this will return you passport token and you can make api request to protected routes.
About passport, email, username, ..... you will have to change database and make it nullable. And add facebook_id field.
And be sure to make requests over https, because your are sending token.
Hope it helps.
in addition to #Bostjan's answer adding my generalised implementation :
SocialAccount here is a laravel model where you'll provider and provider_user_id and local database user id. Below is the example of social_accounts table
And in SocialController :
<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Hash;
use Illuminate\Http\Request;
use App\User;
use App\SocialAccount;
use Socialite;
class SocialController extends Controller
{
public function social(Request $request) {
$provider = $request->input('provider');
switch($provider){
case SocialAccount::SERVICE_FACEBOOK:
$social_user = Socialite::driver(SocialAccount::SERVICE_FACEBOOK)->fields([
'name',
'first_name',
'last_name',
'email'
]);
break;
case SocialAccount::SERVICE_GOOGLE:
$social_user = Socialite::driver(SocialAccount::SERVICE_GOOGLE)
->scopes(['profile','email']);
break;
default :
$social_user = null;
}
abort_if($social_user == null , 422,'Provider missing');
$social_user_details = $social_user->userFromToken($request->input('access_token'));
abort_if($social_user_details == null , 400,'Invalid credentials'); //|| $fb_user->id != $request->input('userID')
$account = SocialAccount::where("provider_user_id",$social_user_details->id)
->where("provider",$provider)
->with('user')->first();
if($account){
return $this->issueToken($account->user);
}
else {
// create new user and social login if user with social id not found.
$user = User::where("email",$social_user_details->getEmail())->first();
if(!$user){
// create new social login if user already exist.
$user = new User;
switch($provider){
case SocialAccount::SERVICE_FACEBOOK:
$user->first_name = $social_user_details->user['first_name'];
$user->last_name = $social_user_details->user['last_name'];
break;
case SocialAccount::SERVICE_GOOGLE:
$user->first_name = $social_user_details->user['name']['givenName'];
$user->last_name = $social_user_details->user['name']['familyName'];
break;
default :
}
$user->email = $social_user_details->getEmail();
$user->username = $social_user_details->getEmail();
$user->password = Hash::make('social');
$user->save();
}
$social_account = new SocialAccount;
$social_account->provider = $provider;
$social_account->provider_user_id = $social_user_details->id;
$user->social_accounts()->save($social_account);
return $this->issueToken($user);
}
}
private function issueToken(User $user) {
$userToken = $user->token() ?? $user->createToken('socialLogin');
return [
"token_type" => "Bearer",
"access_token" => $userToken->accessToken
];
}
}

Cannot login through Facebook in Laravel 5.1

I am trying to login with facebook using Laravel 5.1.
I am following each steps mention in laravel documentation.
http://laravel.com/docs/5.1/authentication#social-authentication.
But, When i login through facebook then it will redirect to my normal login page.
In sort Session is store in facebook login.
This is a Code that is written by me.
Router.php
Route::get('auth/facebook','Auth\AuthController#redirectToProvider');
Route::get('auth/facebook/callback','Auth\AuthController#handleProviderCallback');
AuthController.php
public function redirectToProvider()
{
return Socialite::driver('facebook')
->scopes(['email', 'public_profile'])
->redirect();
}
public function handleProviderCallback()
{
$user = Socialite::driver('github')->user();
$user = Socialite::driver('github')->user();
// OAuth Two Providers
$token = $user->token;
// OAuth One Providers
$token = $user->token;
$tokenSecret = $user->tokenSecret;
// All Providers
$user->getId();
$user->getNickname();
$user->getName();
$user->getEmail();
$user->getAvatar();
}
Services.php
'facebook' => [
'client_id' => '1625567400000000',
'client_secret' => 'secret',
'redirect' => 'http://localhost:8000/',
],
When i type localhost/8000/auth/facebook it will redirect me to facebook and ask permission for public_profile, email etc.
And it will redirect back to localhost/auth/login.
And when i type localhost:8000/auth/facebook/callback in URL, it will through error like this;
ClientException in Middleware.php line 69:
Client error: 404
For your case, I guest you are using middleware to check if the user is already logged in. And this might the problem that you get redirect to localhost/auth/login
I hope following code could be useful to you
public function handleProviderCallback()
{
//retrieve user's information from facebook
$socUser = Socialite::driver('facebook')->user();
//check user already exists in db
$user = \App\User::where('email', $socUser->getEmail())->first();
if($user) {
// if exist, log user into your application
// and redirect to any path you want
\Auth::login($user);
return redirect()->route('user.index');
}
//if not exist, create new user,
// log user into your application
// and resirect to any path you want
$user = new \App\User ;
$user->email = $socUser->getEmail();
// ...
// ...
// ...
$user->save();
\Auth::login($user); // login user
return redirect()->route('user.index'); // redirect
}
note: I did not test my code but you should get some idea
for more information: http://laravel.com/docs/5.1/authentication
and as #mimo mention,
Your redirect url in the Services.php file has to be
localhost:8000/auth/facebook/callback
Your redirect url in the Services.php file has to be
localhost:8000/auth/facebook/callback