How to get Facebook user detail from Access Token using Codeigniter? - codeigniter

I'm really struggling to understand what's happening here. I can get a Users details fine in the OpenGraph tester or just hitting the URL https://graph.facebook.com/me?access_token=VALID_TOKEN or using file_get_contents, but when trying the Codeigniter Facebook Library I get error "An active access token must be used..." and if I just try a CURL GET I get no output. I know the access_token is valid so why aren't they working? The overall objective is to get an access_token from iOS App and use this to do a Like via the web server using og.likes.
My test function:
function me_test(){
$access_token = "VALID_TOKEN";
$url = 'https://graph.facebook.com/me?access_token=';
$url_full = $url.$access_token;
$result = file_get_contents($url_full);
echo $result;
// Try Codeigniter Facebook Library
try {
$user = $this->facebook->api('/me?access_token='.$access_token);
} catch (Exception $e) {
print_r($e);
}
// Codeigniter CURL Library
$this->load->library('curl');
echo $this->curl->simple_get($url_full);
$info = $this->curl->info;
print_r($info);
}

I have also faced this issue and find the alternate way to get userdata. You can try this
function me_test(){
$userId = $this->facebook->getUser(); //This will return the current user id
// Try Codeigniter Facebook Library
try {
$user = $this->facebook->api('/'.$userId);
//When you pass the userid you dont need to provide access token
} catch (Exception $e) {
print_r($e);
}
}

Related

Test Passport's Authorization code grant authentication flow

Any idea on how i can test my authentication routes in authorization code grant:
- GET: '/oauth/authorize/?' . $query
- POST: 'oauth/token'
The problem is that according to the docs you need to provide a redirect_uri field in your query and i don't know how you suppose to have one in tests and then get the response from your laravel app.
i don't want to test this api with my frontend app.(if possible)
i haven't showed any code bc i just need a general idea of the testing process of such APIs that are working with clients and redirect_uris
on google i found tests around password grant authentication which doesn't need a redirect_uri field
this is what i tryed and it failed.
test:
$user = User::orderBy('id', 'asc')->first();
$token = $user->createToken('personal_access');
Passport::actingAs($user, [], 'api');
(new AuthController)->logout();
if (($user = Auth::user()->toArray()) !== null) {
dd(1, $user);
} else {
dd(0);
}
Auth::user() returns the $user
AuthController:
public function logout(): Response
{
$tokenId = $this->getTokenId();
$tokenRepository = app(TokenRepository::class);
$tokenRepository->revokeAccessToken($tokenId);
$refreshTokenRepository = app(RefreshTokenRepository::class);
$refreshTokenRepository->revokeRefreshTokensByAccessTokenId($tokenId);
Artisan::call('passport:purge');
return response('Successfully loged you out.', 200);
}
private function getTokenId(): int
{
return (new CheckAuthentication)->getAuthenticated()->token()->id;
}
$tokenId is always zero.

Pin Verification In Laravel

I'm a beginner. I have a pin field in my user database. I want users to verify the pin before they can access there profile. how can I do this any logic?
in livewire components
public function verify (){
$user = User::select('id')->where('pin',$pin)->first();
Auth::loginUsingId($user->id);
return redirect()->intended('/user');
}
in my livewire blade I will call the verify method in the form will this work
laravel login using pincode :check the following code example may be you get the hint how to implement that, in this example code pin authentication is done using JWT and then user is allowed to access to those specific routes.
$user = User::find($uid);
try {
if (!$token = JWTAuth::fromUser($user)) {
return $this->onUnauthorized();
}
} catch (JWTException $e) {
return $this->onJwtGenerationError();
}
For somereason if you dont want to use the above JWT method you can use this one. i'm sharing the code for an example from by program which may help you
$user = User::select('id')->where('pin',$pin)->first();
Auth::loginUsingId($user->id);
return redirect()->intended('/user');

Using laravel socialite and jwt-auth without session

Short version: What would be the appropriate way to send the JWT generated from Facebook login (laravel/socialite) to the angularjs front end without using session.
Long Version
I am making an app that has angularjs front end and laravel 5.2 backend. I am using tymondesigns/jwt-auth for authentication instead of session.
I am also using laravel/socialite for social Facebook authentication. For that I am using the stateless feature of socialite so that I don't need session in any ways.
The basic authentication works perfectly. But, when I try to use Facebook login, I follow these steps
User clicks on a button on the angular side that redirects to the provider login page of the back end.
public function redirectToProvider() {
return Socialite::with('facebook')->stateless()->redirect();
}
2. User gives his login information. After logging in he is redirected to my handlecallback function.
try {
$provider = Socialite::with('facebook');
if ($request->has('code')) {
$user = $provider->stateless()->user();
}
} catch (Exception $e) {
return redirect('auth/facebook');
}
return $this->findOrCreateUser($user);
Next I use the findorcreate function to determine whether the user exists or not. If not than I just create a new user and create JWT from that.
$user = User::where('social_id', '=', $facebookUser->id)->first();
if (is_object($user)) {
$token = JWTAuth::fromUser($user);
return redirect()->to('http://localhost:9000/#/profile?' . 'token=' . $token);#angular
} else {
$result = array();
$result['name'] = $facebookUser->user['first_name']
$result['email'] = $facebookUser->user['email'];
$result['social_id'] = $facebookUser->id;
$result['avatar'] = $facebookUser->avatar;
$result['gender'] = $facebookUser->user['gender'];
$result['status'] = 'active';
$result['login_type'] = 'facebook';
$result['user_type'] = 'free_user';
try {
$user = User::create($result);
} catch (Exception $e) {
return response()->json(['error' => 'User already exists.'], HttpResponse::HTTP_CONFLICT);
}
$token = JWTAuth::fromUser($user);
return redirect()->to('http://localhost:9000/#/profile?' . 'token=' . $token);#angular
}
My problem is, in the last block of code I am having to send the jwt to my frontend via url. Which isn't secure at all. What would be the right way to send the generated JWT to the frontend without using session. Thank you
The official documentation of Laravel Socialite says:
Stateless Authentication
The stateless method may be used to disable session state verification. This is useful when adding social authentication to an API:
return Socialite::driver('google')->stateless()->user();
Then, you can authenticate using the jwt-auth method:
JWTAuth::fromUser($user)
If you're using $http on the Angular side, try returning the token as a JSON response from Laravel:
return response()->json(compact('token'));
Then store the token in localStorage or sessionStorage or what have you.
If you're generating your Angular page from within Laravel (i.e. not using Laravel as an API, but showing your Angular page from /public/index.php, for instance) you could load the view with the token in the data for the view.
As long as you're using HTTPS either of these two scenarios are better than passing the token in the redirect URL.
You can store token and use client side redirect without storing to browser history to redirect user to profile page without token in URL:
document.location.replace({profile-url})

how to handle laravel socialite "Missing authorization Exception"

In Laravel Socialite We are redirected to facebook. But When User Cancels (not allowing facebook to access public profile) it is giving error Missing Authorization exception
ClientException in RequestException.php line 107: Client error: GET
https://graph.facebook.com/oauth/access_token?client_id=1309844325833234&client_secret=1304bbdd28400tret49a295d324d577c&redirect_uri=http%3A%2F%2Flocalhost%3A8000%2Fauth%2Ffacebook%2Fcallback`
resulted in a 400 Bad Request response: {"error":{"message":"Missing
authorization
code","type":"OAuthException","code":1,"fbtrace_id":"Aq9wMwG6ewl"}}
I dont want to display this Instead I Want to return to my site home page by giving a message "Facebook Login Failed" like what shown in stackoverflow facebook login.
Finally i got answer.Here it is
public function handleProviderCallback()
{
try {
$user = Socialite::driver('facebook')->user();
} catch (\Exception $e) {
//Here you can write excepion Handling Logic
}
}
Try catch didn't give good result to me. I used below methods to catch this error. If you're using Laravel Socialite library definitely it has function call handleProviderCallback. In that use this code
handleProviderCallback Method
/**
* Obtain the user information from GitHub.
*
* #return Response
*/
public function handleProviderCallback()
{
$error_code = Input::get('error_code');
if ($error_code == 200)
{
return redirect()->route('sign-in')->with('error','You\'ve chose not to grant us permission to connect with your Facebook account.');
}
else
{
$fbUser = Socialite::driver('facebook')->user();
# rest of your code
}
}
Where does this error_code come from ??
Well, If you look at the error page(Laravel Black screened) come to you check the URL of that page. It has the these get methods error , error_code , error_description , error_reason , state.
Ex : http://localhost:8000/login/facebook/callback?error=access_denied&error_code=200&error_description=Permissions+error&error_reason=user_denied&state=mIxNjoDCogT2piMV5LX1Imk6GWNzqPUt3JZaqsIo#_=_
What I can do this to optimize this
You can use a switch statement based on error Check this Facebook error codes, with an error message and pass it.

How to authenticate an already logged in facebook user with facebook api

I am using facebook login in my codeigniter application. I have set up the controller to handle the login and it seems like it's working on all user-state cases except when the user is logged into facebook and is trying to log into my application but has never authenticated it.
Here is my facebook controller index function:
$data=array(
'redirect_uri' => site_url('facebookcontroller/handle_facebook_login'),
'scope' => 'publish_stream,email'
);
redirect($this->fbconnect->getLoginUrl($data));
Does ->getLoginUrl() direct only to the facebook login page but not the authentication page?
I appreciate any help
It seems you are using an old version of the facebook sdk. I recommend taking a look here, as some of those functionalities are not working anymore.
then take into consideration that, when someone is logged into facebook and you ask for the profile info like this:
$data['user_profile'] = $profile = $this->facebook->api('/me');
It may be using an out of date access token, so you have to enclose that call in a try-catch block, like this:
try {
$data['user_profile'] = $profile = $this->facebook->api('/me');
}catch (Exception $e){
$this->facebook->setAccessToken($this->facebook->getAccessToken());
try {
if($this->facebook->getUser()) {
$this->facebook->api(array('method' =>'auth.revokeAuthorization' ));
}
}catch(Exception $e) {
redirect('<login controller>');
}
redirect('<login controller>');
}

Resources