I have a laravel app with integrated with 2 factor authentication using Nexmo API . I have manage to verify the code in the login process . so now i need to re-send the verification again ..
I already followed this article and called same method again but it's not working
https://www.nexmo.com/blog/2017/07/26/2fa-logins-laravel-nexmo-dr/
Here is Re-Send Button
Re-Verify
Here is the route
Route::get('/reverify', 'Auth\LoginController#reauthenticated')->name('reverify');
Here is the Re-Send Code
public function reauthenticated(Authenticatable $user)
{
$verification = Nexmo::verify()->start([
'number' => $user->phone_number,
'brand' => 'Ezy verification'
]);
$request->session()->put('verify:request_id', $verification->getRequestId());
return redirect('verify');
}
So I just need to know how can I resend the verification code
Related
In my laravel project, i created the authentication successfully. register, login, and logout works fine. i did made the email verification, it sends the verification email to the user successfully. but when i click the verification email sended to my gmail by laravel, it redirects me to a page which says: 403 This action is unauthorized.
I am using Laravel 7.
my routes in web.php file
Route::get('/', function () {
return redirect(app()->getLocale());
});
Route::get('email/verify', 'Auth\VerificationController#show')->name('verification.notice');
Route::get('email/verify/{id}', 'Auth\VerificationController#verify')->name('verification.verify');
Route::post('email/resend', 'Auth\VerificationController#resend')->name('verification.resend');
Route::group([
"prefix" => "{language}",
'where' => ['locale' => '[a-zA-Z]{2}'],
'middleware' => 'setlocale'
], function () {
Auth::routes();
Route::get('/home', 'HomeController#index')->name('home');
});
I set the email verification routes manually, because priviously when i set the
Auth::routes(['verify' => true]);
I got an error, so i set the email verification outside the route group manually to fix that error.
In verify.blade.php the resend verification email also works fine, it resends the verification email successfully.
I have solved the problem. the problem was that verification.verify route was wrong,
when you set the
Auth::routes(['verify' => true]);
the actual verification.verify route is like this
email/verify/{id}/{hash}
The verification.verify route calls verify method which is located in vendor\laravel\ui\auth-backend\VerifiesEmails.php In this method there are two if statements which throws AuthorizationException which causes 403 This action is unauthorized page. The first if checks the route user id with the current authenticated user id, and the second if checks the route hash with the current authenticated user hash.
And make soure to configure your trusted proxies correctly.
check in laravel documentation click here.
I hope this help you.
I my case I was clicking the wrong 'verify email url' Because my all verfication emails in google were accumulating under same 'Subject' so instead of clicking the last email, I was clicking the first email
I have used laravel auth and socialite package in my web app. I have followed https://www.youtube.com/watch?v=uavoKwhGBKI&t=932s link and it working fine.To be brief, If I register using socialite it fetches the name of the user and email but needs to be filled other details as DOB and password but if I submit without filling that it shows 500 error while if I register without socialite then my validation works fine.The registration page is same.
Socialite only gives you access to a select set of data returned from a successful connection.
# Retrieving User Details
https://laravel.com/docs/6.x/socialite#retrieving-user-details
$user = Socialite::driver('github')->user();
// OAuth Two Providers
$token = $user->token;
$refreshToken = $user->refreshToken; // not always provided
$expiresIn = $user->expiresIn;
// OAuth One Providers
$token = $user->token;
$tokenSecret = $user->tokenSecret;
// All Providers
$user->getId();
$user->getNickname();
$user->getName();
$user->getEmail();
$user->getAvatar();
# Modifying LoginController
https://scqq.blogspot.com/2017/11/laravel-55-socialite-login-with-twitter.html
This guide you followed does not actually register a user by social platform. It only pre-populates the default Laravel registration form with the fields name and email as shown below. This is where you can add another property from above, such as the user's avatar, if desired. You would also need to add the corresponding field to the registration form.
return view('auth.register', [
'name' => $userSocial->getName(),
'email' => $userSocial->getEmail(),
// ... 'avatar' => $userSocial->getAvatar(),
]);
Google is NEVER going to give you someone's password!
The whole point of Socialite is to allow Google (or the selected provider) to authenticate the user — not your application.
If you wish to actually register a user with Socialite (without any additional forms or setting a password), you will need to modify or extend RegisterController.php to be able to support this.
I'm getting Token required error while already Enabled route option but still, it's not working.
by using this library : https://github.com/JoeDawson/youtube
could you help me to solve this problem?
Code :
class VideoController extends BaseController {
public function __construct(){
}
public function store(Request $request){
$video = Youtube::upload($request->file("video")->getPathName(), [
'title' => 'My Video',
'description' => 'This video is uploaded through API.',
'tags' => ['api', 'youtube'],
]);
return $this->sendResponse($video);
}
}
According to the documentation of that package you need to do these steps, because you may have problem with refresh_token (I guess you don't have any token in your database which must be created after logging in google)
It's important that before you begin uploading a video, you have confirmed that you have a refresh_token in your database if not these steps have to be helpful.
1- Delete all of your tokens in the youtube_access_tokens table.
2- Enable routes in youtube.php
3- Re-authenticate with Google
4- Check your youtube_access_tokens table and find the most recent token.
5- Review the token and ensure a refresh_token exists.
6- Disable authentication routes in config/youtube.php
briefly, for creating a token You need to visit your Google console and add your URL as the callback (localhost).
Then in your app, visit http://localhost:8000/youtube/auth - you will be redirected to Google and will be asked to log in. This is when you get a token and then you may not see that error again!
As detailed in my question to the the Google API team, I would like to work out a way to avoid redirects.
In theory this should be possible as an Authentication Code from one client (JavaScript) should be agnostic of the client and thus it should work if passed to the PHP client to fetch the access and refresh tokens.
Steps in theory:
Client gets an authorization code
Client exchanges the authorization code for the access and refresh tokens
How am I attempting this?
Run the JavaScript client to get the Authentication token
GoogleAuth = gapi.auth2.getAuthInstance()
GoogleAuth.grantOfflineAccess({
scope: 'https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/plus.business.manage https://www.googleapis.com/auth/plus.me openid email profile'
}).then(function (resp) {
var auth_code = resp.code;
console.log("AuthCode:" + auth_code)
})
At this point i get a code, not sure if this is an authorization code or access token but i cannot see any other function in the Javascript library that is Authorization token explicit/specific.
Use the Authentication Token in the PHP API Library
$error = $request->get('error');
$code = $request->get('code');
if($error){
throw new Exception('Error from authenticating ' . $error);
}
$client = new \Google_Client();
$client->setAuthConfig(getcwd() . '/../client_secret.apps.googleusercontent.com.json');
$client->setAccessType("offline"); // offline access
$client->setIncludeGrantedScopes(true); // incremental auth
$client->addScope(
array(
'https://www.googleapis.com/auth/userinfo.email',
'https://www.googleapis.com/auth/userinfo.profile',
'https://www.googleapis.com/auth/plus.business.manage'
)
);
$client->setRedirectUri('http://myserver.com/code');
$client->setApprovalPrompt('force');
$client->fetchAccessTokenWithAuthCode($code);
$accessToken = $client->getAccessToken();
return new Response(
"<html><body>Authenticated with code : " . $code . "<br/>\n\n".
" Access Token is : ". var_export($accessToken, true) . "</body></html>"
);
Access token is still null. the line $accessToken = $client->getAccessToken(); returns null or false.
This works in the full PHP based version but the PHP version is based on creating a link that the user needs to follow, the user is then on the Google server and can approve the app, when approved the user is redirected back to the app. Then the app receives the Authentication code.
I just would like to avoid redirects due to the architecture of single pages apps or just preference. The only alternative I can think of is to open a popup and notify the original window when access and refresh codes are returned so that the PHP client can go on querying the API, but it is an ugly solution IMHO.
Is there another way to get an authorization code that works on PHP but obtained from JavaScript?
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})