I followed this tutorial on how to use socialite -> https://laracasts.com/series/whats-new-in-laravel-5/episodes/9
This is what I've done:
Added to my composer.json
"laravel/socialite": "^2.0",
"laravelcollective/html": "5.1.*#dev"
Added to my app.php
providers
Laravel\Socialite\SocialiteServiceProvider::class,
Collective\Html\HtmlServiceProvider::class,
aliases
'Socialite' => Laravel\Socialite\Facades\Socialite::class,
'Form' => Collective\Html\FormFacade::class,
'Html' => Collective\Html\HtmlFacade::class,
Added to services.php
'github' => [
'client_id' => 'myid',
'client_secret' => 'mysecret',
'redirect' => 'http://inspectorhost.app/login',
],
Added to routes.php
Route::get('/', function () {
if (Auth::check()) return 'Welcome back, ' . Auth::user()->username;
return 'Hi guest. ' . link_to('login', 'Login with Github!');
});
Route::get('login', 'AuthController#login');
Created an AuthController and added
class AuthController extends Controller
{
public function login(){
return \Socialite::with('github')->redirect();
}
}
I'm using nginx and I set it up so it doesn't need to use the public folder to acccess the web
root home/inspectorhost.app/public_html/public/;
So when I click on 'Login with Github', instead of sending me to Github to authorize the login, it sends me to /login and gives me a 404 error.
EDIT
Now it gets interesting... when I go to http://inspectorhost.app and click in 'Login with Github' I get the error from above (404) however if I run php artisan serve and I access the app from localhost:8000 it works... so I guess it might be some misconfiguration on nginx?
Any help is appreciated.
Open in private window. because after first time session store in github if your github login in other tab
Related
I'm using laravel jetstream with the livewire stack. In my fortify.php file this is the code. I havent changed anything, i just enabled the feature to verify the email when user signs up.
"features" => [
Features::registration(),
Features::resetPasswords(),
Features::emailVerification(),
Features::updateProfileInformation(),
Features::updatePasswords(),
Features::twoFactorAuthentication([
"confirm" => true,
"confirmPassword" => true,
// 'window' => 0,
]),
And implemented MustVerifyEmail in my User.php model like this class User extends Authenticatable implements MustVerifyEmail. ALso updated BROADCAST_DRIVER=log in .env file. When I click the link that I get in laravel.log file:
If you're having trouble clicking t=
he "Verify Email Address" button, copy and paste the URL below
into your =
web browser: [http://127.0.0.1:8000/email/verify/5/93cfe97ab6a2d5ecbbce5edf=
47197fdb28f54ad1?expires=3D1675106924&signature=3D7d26bcec33531228b2c66a419=
9fd5a15ab72ae07a1650a41213d09da00d92109](http://127.0.0.1:8000/email/verify=
/5/93cfe97ab6a2d5ecbbce5edf47197fdb28f54ad1?expires=3D1675106924&signature=
=3D7d26bcec33531228b2c66a4199fd5a15ab72ae07a1650a41213d09da00d92109)
I get not found error in my browser. This is also my web.php file:
Route::middleware(['auth:sanctum',config('jetstream.auth_session'),
'verified'
])->group(function () {
Route::get('/dashboard', function () { return view('dashboard'); })
->name('dashboard');
Route::get('/skills', function () { return view('skills'); })
->name('skills');
});
What am I doing wrong?
Following a tutorial: https://www.twilio.com/blog/build-secure-api-php-laravel-passport
I manAged to get Laravel/Passport installed formy Laravel Api and Vue application.
I managed to create attoken with:
localhost:8000/oauth/token
get the login working in Postman:
localhost:8000/api/login?email=jennie05#example.com&password=password
Now when I try to register a user I get returned to the home-page.
I do get some "undefined method" errors from VS Code, but they show up in the login method,
and not in the failinf register method:
Here is the controller:
<?php
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\User;
class AuthController extends Controller
{
public function register(Request $request)
{
$validatedData = $request->validate([
'name' => 'required|max:55',
'email' => 'email|required|unique:users',
'password' => 'required|confirmed'
]);
$validatedData['password'] = bcrypt($request->password);
$user = User::create($validatedData);
$accessToken = $user->createToken('authToken')->accessToken;
return response([ 'user' => $user, 'access_token' => $accessToken]);
}
public function login(Request $request)
{
$loginData = $request->validate([
'email' => 'email|required',
'password' => 'required'
]);
if (!auth()->attempt($loginData)) {
return response(['message' => 'Invalid Credentials']);
}
$accessToken = auth()->user()->createToken('authToken')->accessToken;
return response(['user' => auth()->user(), 'access_token' => $accessToken]);
}
}
In these are the routes in api.php:
Route::post( 'register', 'App\Http\Controllers\API\AuthController#register');
Route::post( 'login', 'App\Http\Controllers\API\AuthController#login');
// Route::prefix('v2')->group(function(){ // prefix voor versie 2
Route::apiResource('/cards', 'App\Http\Controllers\CardController');
Route::apiResource('/games', 'App\Http\Controllers\GameController');
//Route::get('games', 'App\Http\Controllers\GameController#index')->middleware('auth:api');
//Route::post('games', 'App\Http\Controllers\GameController#store')->middleware('auth:api');
//Route::get('games/{id}', 'App\Http\Controllers\GameController#show')->middleware('auth:api');
//Route::put('games/{id}', 'App\Http\Controllers\GameController#update')->middleware('auth:api');
//Route::delete('games/{id}', 'App\Http\Controllers\GameController#destroy')->middleware('auth:api');
Route::get('/gameByPin/{pin}', 'App\Http\Controllers\GameController#searchPin');
Route::apiResource('/speler', 'App\Http\Controllers\SpelerController');
//});
Route::middleware('auth:api')->get('/user', function (Request $request) {
return $request->user();
});
is there anyone who can help troubleshooting this?
Postman does not give me errors, just the redirect to homepage..
Wow,
Thanks Patrick, your the best.
Just checked all the steps in the documentation.
reran the installation command I ran when setting up everything. ( Apperently need to do this twice ?!):
php artisan passport:install
It returned:
Encryption keys already exist. Use the --force option to overwrite them.
Personal access client created successfully.
Client ID: 5
Client secret: ikJEfthxxxxxxxxxxxxxxxxxxxxxxxxxxxBjJ36
Password grant client created successfully.
Client ID: 6
Client secret: H42lpMxxxxxxxxxxxxxxxxxxxxxxxxxxxQGZgH
Now the post request results in a token!
The error VS Code shows d for "use HasApiToken" is:
Undefined type 'Laravel\Passport\HasApiTokens'.intelephense(1009)
Background
I have developed a React app that uses Laravel as an API. I have added logins via Passport and have been using the Personal Access Client approach quite successfully. I can add new users and tokens, I can revoke tokens, I can reset passwords... All API calls (except login and register) are guarded by the API middleware and it works. If I remove the Bearer ${token} from the header on any of these calls it returns 401 unauthenticated due to the ->middleware('auth:api') wrapper.
The Problem
Everything works completely as expected... until I move everything to my Raspberry Pi server. As soon as I moved everything, the problem began. I can login and I can register, but as soon as I use the new bearer token (that I received from my login or register call(s)) on any of the endpoint calls that follow in my flow, it fails with 401 unauthenticated, immediately. I ran the php artisan passport:client --personal command and successfully entered the id and secret into my .env file as usual. I installed all the composer and vendor packages. I installed all passport package(s) and CLI commands.
It only fails on calls that use the auth middleware.
I have done some digging and it seems the only change I can find (significantly) is that the Pi runs a 32 bit PHP where my localhost runs a 64 bit PHP. Other than that its the same code, DB, versions of Laravel and PHP, everything.
I have tried using the command php artisan passport:client --personal --name="app-name" --redirect_uri="http://192.168.1.1/" which puts a record in the "oauth_clients" table but shows the redirect as http://localhost/. I then try to use SQL to change the value of the column named "redirect" to http://localhost/, manually... but again the change does nothing. Calls still return 401 unauthenticated.
The only other things I can find that might be an issue are:
The fact that all tokens in the database table "oauth_access_tokens", under the column called "redirect", are created with the redirect_uri of http://localhost. No matter what I do it's always localhost and not my servers domain or IP address (which is concerning). Manually changing SQL as I said does nothing but I know Laravel uses a few "read-only" columns for auth so I wonder if this is one of them... perhaps personal access tokens only work on localhost?
My email_verified_at column in my "users" table (generated by passport commands) is null because I was not able to setup the "forgot my password" flow of Passport on localhost since emails won't send out on localhost.
What I have setup is this:
public function boot()
{
$this->registerPolicies();
Passport::pruneRevokedTokens();
Passport::tokensExpireIn(Carbon::now()->addDays(1));
Passport::refreshTokensExpireIn(Carbon::now()->addDays(14));
Passport::personalAccessTokensExpireIn(Carbon::now()->addDays(1));
}
AuthServiceProvider Class
public function register(Request $request) {
$validatedData = $request->validate([
'image_url' => 'required',
'last_name' => 'required|max:55',
'image_url' => 'required|max:250',
'first_name' => 'required|max:55',
'password' => 'required|confirmed',
'email' => 'email|required|unique:users',
]);
$validatedData['password'] = bcrypt($request->password);
if ($request->hasFile('image_url')) {
$imageFile = $request->file('image_url');
$imageExtension = $imageFile->extension();
if (strtolower($imageExtension) === 'png' || strtolower($imageExtension) === 'jpg') {
$validatedData['image_url'] = Storage::url( $request->file('image_url')->store('user_pics', 'public') );
}
$user = User::create($validatedData);
date_default_timezone_set('UTC');
$date = new \DateTime( date('Y-m-d H:i:s') );
$user->email_verified_at = $date->format('c');
$accessToken = $user->createToken('authToken-'.$user->id, ['*'])->accessToken;
return response([ 'user' => $user, 'access_token' => $accessToken ]);
} else {
abort(404, 'Cannot register user without a user image!');
}
}
public function login(Request $request) {
$loginData = $request->validate([
'email' => 'email|required',
'password' => 'required'
]);
if (!auth()->attempt($loginData)) {
return response()->json(['statusText' => 'Unauthorized'], 401);
}
$user = auth()->user();
$accessToken = auth()->user()->createToken('authToken-'.$user->id, ['*'])->accessToken;
return response([ 'user' => $user, 'access_token' => $accessToken ]);
}
public function logout(Request $request) {
if (auth()->guard('api')->check()) {
auth()->guard('api')->user()->OauthAcessToken()->delete();
return response()->json([ 'msg' => 'Successfully logged out!' ]);
} else {
return abort(404, 'Must be logged in to log a user out');
}
}
public function refreshToken(Request $request) {
if (auth()->guard('api')->check()) {
$user = auth()->user();
$accessToken = auth()->user()->createToken('authToken-'.$user->id, ['*'])->accessToken;
return response([ 'user' => $user, 'access_token' => $accessToken ]);
} else {
return abort(404, 'Must be logged in to refresh a token!');
}
}
AuthController Class
'defaults' => [
'guard' => 'web',
'passwords' => 'users',
],
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'passport',
'provider' => 'users'
],
],
config/Auth.php
APP_NAME=MyName
APP_ENV=dev
APP_DEBUG=true
APP_URL=http://192.168.1.1
PASSPORT_PERSONAL_ACCESS_CLIENT_ID="1"
PASSPORT_PERSONAL_ACCESS_CLIENT_SECRET="[SOME LONG HASH]"
.env File
Finally solved it!!
Turns out it was Apache on the Raspberry Pi server blocking the Authorization header. This finally unblocked me and solved my issues.
For anyone else coming from a Google search, you can go into your /etc/apache2/apache2.conf file and at the very bottom, paste:
SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1
I am using a Raspberry Pi 4 with 32 bit PHP and Apache2.
Also, I didn't mention in my post that I have been using the following for my apache server root htaccess:
# Handle Authorization Header
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
.htaccess file, server root
I am using "laravel/socialite": "^3.0", to facebook login. But it shows
an error
Type error: Argument 1 passed to Laravel\Socialite\SocialiteManager::formatRedirectUrl() must be of the type array, null given, called in /var/www/html/mas/vendor/laravel/socialite/src/SocialiteManager.php.
It happens when I am calling the below function in my login controller
public function socialLogin($social)
{
return Socialite::driver($social)->redirect();
}
Hi you are missing to give credentials of social media put that in config/services.php
'facebook' => [
'client_id' => env('FACEBOOK_CLIENT_ID'),
'client_secret' => env('FACEBOOK_CLIENT_SECRET'),
'redirect' => env('CALLBACK_URL_FACEBOOK'),
],
'google' => [
'client_id' => env('GOOGLE_CLIENT_ID'),
'client_secret' => env('GOOGLE_CLIENT_SECRET'),
'redirect' => env('CALLBACK_URL_GOOGLE'),
],
'twitter' => [
'client_id' => env('TWITTER_CLIENT_ID'),
'client_secret' => env('TWITTER_CLIENT_SECRET'),
'redirect' => env('CALLBACK_URL_TWITTER'),
],
'linkedin' => [
'client_id' => env('LINKEDIN_CLIENT_ID'),
'client_secret' => env('LINKEDIN_CLIENT_SECRET'),
'redirect' => env('CALLBACK_URL_LINKEDIN'),
],
'instagram' => [
'client_id' => env('INSTAGRAM_CLIENT_ID'),
'client_secret' => env('INSTAGRAM_CLIENT_SECRET'),
'redirect' => env('CALLBACK_URL_INSTAGRAM'),
],
You must clear the configuration cache file, how? if you use php artisan you will see the command config:clear. Run it:
php artisan config:clear
and now if you access to the $config variable inside the Laravel\Socialite\SocialiteManager::createFacebookDriver()
you will get the configuration element stored in config/services.facebook (Facebook, for example) that before was not 'visible' for Socialite.
In short: run php artisan config:clear
This happened to me just recently, fixed it after reading the following post here on StackOverflow:
Why do I have to run "composer dump-autoload" command to make migration work in laravel
The solution is basically to run the following commands:
php artisan clear-compiled
composer dump-autoload
php artisan optimize
The problem is with the parameters passed to the function socialLogin($social).
Try by manually setting the 'github' or 'facebook' string in the drvier function of Socialite.
Dont forget to mention 'github' , 'facebook, etc in the route in web.php
I had same problem.
I got this errot because of copy/paste while reading Laravel doc. In my case in loginController.php changed this:
// I copied this from Laravel doc
public function redirectToProvider()
{
return Socialite::driver('github')->redirect();
}
//What I really needed
public function redirectToProvider()
{
return Socialite::driver('google')->redirect();
}
I was having the same issue even after had set up my config/services.php file and managed to solve it by clearing my cache. In your project directory run
php artisan optimize:clear
php artisan cache:clear
php artisan config:clear
php artisan config:cache
This ensures that your entire cache is cleared.
NOTE: changing core files in Laravel most of the times require you running the above commands as Laravel tends to use caching to a greater extend to improve on application speeds
Try these
Check if you have all your social media in config/services.php
On your register or login page check the url that corresponds to facebook
a href="{{ url('/login/facebook') }}"
Go to Routes and check if you have routes properly configured
Route::get('login/{social}', 'Auth\LoginController#redirectToProvider');
Route::get('login/{social}/callback', 'Auth\LoginController#handleProviderCallback');
Open Auth/LoginController and check if have
use Socialite;
public function redirectToProvider($social)
{
Socialite::driver($social)->redirect();
}
public function handleProviderCallback($social)
{
$user = Socialite::driver($social)->user();
}
As you've mentioned you are only facing the error with facebook, im pretty sure it must be in first three steps
Open vendor\laravel\socialite\src\SocialiteManager.php
Replace to
protected function formatRedirectUrl(array $config)
{
$redirect = value($config['redirect']);
return Str::startsWith($redirect, '/')
? $this->app['url']->to($redirect)
: $redirect;
}
Open vendor\laravel\socialite\src\SocialiteManager.php and
Replace
protected function createFacebookDriver()
{
$config = $this->app['config']['services.facebook'];
return $this->buildProvider(
FacebookProvider::class, $config
);
}
To
protected function createFacebookDriver()
{
$config = $this->app['config']['services.stripe.facebook'];
return $this->buildProvider(
FacebookProvider::class, $config
);
}
I made the files for authentication using the command
php artisan make:auth
I've read on the internet that register, login, as well as logout should work properly, but localhost:8080/logout doesn't work, and I don't know why.
I also read something about modifying AuthController in app, but I do not have that file.
I tried to do it by hand, which means I created a middleware LogoutRedirect:
public function handle($request, Closure $next)
{
return redirect(pages.logout);
}
In the routes I added
use App\Http\Middleware\LogoutRedirect;
Route::get('logout', function()
{
return view('pages.logout');
})->middleware(LogoutRedirect::class);
And logout.blade.php looks like
{{ Auth::logout() }}
I get the error (when trying to access localhost:8080/logout)
Use of undefined constant pages - assumed 'pages'
What could I do about it?
EDIT
I tried another approach (but with no better results):
renamed the route which redirects to '/' to 'home'
made a LogoutController in app/http/Controllers/Auth
namespace App\Http\Controllers;
use [...]
class LogoutController extends Controller
{
public function logout() {
Auth::logout();
return Redirect::route('home');
}
}
made the route
Route::post('logout', array(
'as' => 'account-sign-out',
'uses' => 'Auth\LogoutController#logout'
));
The error I get is
MethodNotAllowedHttpException in RouteCollection.php line 233:
That's the same error I get when I try to use the default logout defined in auth
You are trying to access the logout page with GET. But this doesn't work because your logout route is a post route.
Change
Route::post('logout', array(
'as' => 'account-sign-out',
'uses' => 'Auth\LogoutController#logout'
));
by
Route::get('logout', [
'as' => 'account-sign-out',
'uses' => 'Auth\LogoutController#logout'
]);
When you go to the /logout route with the method GET(The default when you go to a page) it should work.