I'm working on a new Laravel 4 project and i would like to secure the authentication route over the SSL protocol and honestly i searched for 2 days with no luck and i have no idea how to do that.
That's my routes.php file:
Route::group(array('before' => 'guest'), function(){
/*==========================
| csrf PROTECTION
*///========================
Route::group(array('before' => 'csrf'), function(){
/*==========================
| Post Sign-in
*///========================
Route::post('/account/sign-in', array(
'as' => 'account-sign-in-post',
'uses' => 'AccountController#postSignIn'
));
});
/*==========================
| Get Sign-in
*///========================
Route::get('/account/sign-in', array(
'as' => 'account-sign-in',
'uses' => 'AccountController#getSignIn'
));
});
i would like to know if is that even possible using wamp, or it can be only done using a real host server, any help would be appreciated, and sorry for my bad English.
You can force routes to serve using https. For example:
Route::get('account/sign-in', array('https', function()
{
return 'Must be over HTTPS';
}));
ref: http://laravel.com/docs/routing
Related
devs,
so I have been struggling with this problem for about 10 hours now, and I can't seem to find a solution online, worst is that I don't even know why it happens.
I am working on a project which uses PHP LARAVEL as the backend and I started writing the API for the flutter frontend to consume then I ran into this error while trying to test the API endpoint for registering and logging in.
The problem is the process fails with this error when I try to generate or create a token for the registered user or logged-in user.
Here a snapshot of my register function
public function store(Request $request)
{
$validated = Validator::make($request->all(),[
"email" => "required|email",
"password" => 'required',
"first_name"=> "required",
"last_name" => "required",
"phone_number" => 'required',
]);
if ($validated->fails()) {
return response()->json(['errors' => "Invalide credentials"], 403);
}
$user = User::create(
// [
// 'first_name' => $request->first_name,
// 'last_name'=> $request->last_name,
// 'email' => $request->email,
// 'password' => bcrypt($request->password),
// 'phone_number' => $request->phone_number,
// ]
$request->toArray()
);
Auth::guard('api')->check($user);
// $newUser = User::find($user->id);
$token = $user->createToken('authToken')->accessToken;
// return $token;
return response(['token' => $token, 'first_name'=>$user->first_name, 'email'=>$user->email ], 200);
}
The login and register functions all look the same at this point.
Error-causing code is :
$token = $user->createToken('authToken')->accessToken;
Please I am open to your suggestions, thanks.
I finally found a solution for this error and I believe it will help anyone out there with a similar problem.
The problem originates from the fact that your application is unable to asign a unique id to your client, remember your website or mobile app is a client to the backend with also(your mobile app or website) might have other users, so laravel passport will need to identify it with a unique id, below are some of the steps i used to fix this error.
First it originates because during the passport installation, i forgot to install
Blockquote
--uuids
If you have a similar error, follow the steps below to fix:
NOTE: You must have laravel passport installed already, if not, them follow the complete installtion guide Here
Step 1:
Install passport uuids
php artisan passport:install --uuids
Your result will look something like
After creating, the uuid for your application, you will have to include it in your .env file as such:
PASSPORT_PERSONAL_ACCESS_CLIENT_ID=986eb40c-0458-4b6e-bead-ea2fc4987033
PASSPORT_PERSONAL_ACCESS_CLIENT_SECRET=VXLdTpqWK9i3CBqFwZgje5fuerQ5Uf2lvwXJqBoP
And there you go, you can now try to do what you couldn't do before.
I am using Laravel Sanctum with Vuejs SPA. Both reside on same top level domain
Laravel backend : app.demo.localhost
Vue SPA : app-spa.demo.localhost
Login and logout (endpoints) are working correctly when called from VueJS SPA using axios and XSRF-TOKEN is succesfully set, but when I call other api end points it gives me 401 unauthorized.
In axios this is being set
axios.defaults.withCredentials = true;
I have the below configurations
In Laravel .env
SESSION_DRIVER=cookie
SESSION_DOMAIN=.demo.localhost
SANCTUM_STATEFUL_DOMAINS=app-spa.demo.localhost
In Routes/Api.php
Route::middleware('auth:sanctum')->get('api/user', function (Request $request) {
return $request->user();
});
In cors.php
'paths' => ['api/*', 'sanctum/csrf-cookie', 'login', 'logout'],
'allowed_methods' => ['*'],
'allowed_origins' => ['*'],
'allowed_origins_patterns' => [],
'allowed_headers' => ['*'],
'exposed_headers' => [],
'max_age' => 0,
'supports_credentials' => true,
Could someone help me out please?
If you are using php artisan serve add the port number to SANCTUM_STATEFUL_DOMAINS. So if your port number is 8000:
SESSION_DRIVER=cookie
SESSION_DOMAIN=.demo.localhost
SANCTUM_STATEFUL_DOMAINS=app-spa.demo.localhost:8000
Your SANCTUM_STATEFUL_DOMAINS must match the url in your browser. The port number should not be on the SESSION_DOMAIN.
Following are the 8 steps that I follow while setting up Laravel sanctum check if you missed anything
Step1 composer require laravel/sanctum
Step2 php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider
Step3 php artisan migrate (you can ignore this if you're using spa)
Step4 uncomment this line from app/http/kernel.php \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
Step5 In config/cors.php update 'supports_credentials' => true,
Step6 In .env file update SESSION_DRIVER=cookie & add new line of SESSION_DOMAIN=localhost (even if your using any port like 8080 just mention localhost in session_domain)
Step7 In config/sanctum.php add your client domain along with port(if local) in stateful as follows, in my case for vue CLI it's usually localhost:8080 & for nuxt its localhost:3000 , code is as follows
'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf(
'%s%s',
'localhost,localhost:8000,localhost:8080,localhost:3000,127.0.0.1,127.0.0.1:8000,::1',
env('APP_URL') ? ','.parse_url(env('APP_URL'), PHP_URL_HOST) : ''
))),
Mostly if your stateful (step7) is not setup properly you will get 401 unauthorized or it will try to redirect you to the home page along with cors policy error
Step8 Do not forget to await until sanctum/csrf-cookie promise is resolved
async login() {
await axios.get("http://localhost:8000/sanctum/csrf-cookie");
await axios.post("http://localhost:8000/login", {
email: "kunal#gmail.com",
password: "password",
});
let response = await axios.get("http://localhost:8000/api/user");
console.log(response.data);
},
For anyone dealing with localhost:
SESSION_DRIVER=cookie
SESSION_DOMAIN=localhost
SANCTUM_STATEFUL_DOMAINS=localhost:8080(port number you use)
I just encountered the same problem. I configured all the options according to the official documentation, but I couldn't get the authorization.
Then I use routes/web.php instead of routes/api.php, so I can use sanctum middleware very well.
Now the problem seems obvious,Axios withCredentials maybe need to place in the correct way.
const http = axios.create({
baseURL: API_URL,
withCredentials: true
})
maybe not work. So I add {withCredentials: true} like
http.get('/api/whoami', {withCredentials: true})
.then(res => {
console.log(res.data)
})
Then it works.
But the very strange thing is that it is normal now, no matter whether I clear the browser cache, cookies or Laravel's various caches, there is no previous situation
For me i just had to place the host with port number:
SANCTUM_STATEFUL_DOMAINS=127.0.0.1:5173
and it started working.
Maybe this helps someone.
My problema was.... (no read with attention)
If your SPA needs to authenticate with private / presence broadcast channels, you should place the Broadcast::routes method call within your routes/api.php file:
Hi i found a solution.
My SPA is Vue v3 working on 3000 port.
Also my backend is working on 80 port. (laravel 8.1)
Make Stateful Domains in config/sanctum.php like that
'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf(
'%s%s',
'localhost:3000',
env('APP_URL') ? ','.parse_url(env('APP_URL'), PHP_URL_HOST) : ''
))),
Adding only one and correct domain on their, worked for me magically. I wrote before there whole possible variant of ports, it made me crazy and cost a couple days and nights.
My issue was I setup the domain in the wrong place.
I thought was an array of domains, in config/sanctum.php, but not, needs to be placed within the string:
OK:
'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf(
'%s%s',
'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1,myownlocaldomain.test,myownlocaldomain.test:8080', <-------- OK
env('APP_URL') ? ','.parse_url(env('APP_URL'), PHP_URL_HOST) : ''
))),
BAD:
'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf(
'%s%s',
'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1',
env('APP_URL') ? ','.parse_url(env('APP_URL'), PHP_URL_HOST) : '',
'myownlocaldomain.test', <----- BAD
'myownlocaldomain.test:8080', <---- BAD
))),
I hope I save days of work to someone else...
I hope someone could explain why I'm unauthenticated when already has performed a successfull Oauth 2 authentication process.
I've set up the Passport package like in Laravel's documentation and I successfully get authenticated, receives a token value and so on. But, when I try to do a get request on, let say, /api/user, I get a Unauthenticated error as a response. I use the token value as a header with key name Authorization, just as described in the docs.
Route::get('/user', function (Request $request) {
return $request->user();
})->middleware("auth:api");
This function is suppose to give back my self as the authenticated user, but I'm only getting Unauthenticated. Likewise, if I just return the first user, I'm again getting Unauthenticated.
Route::get('/test', function(Request $request) {
return App\User::whereId(1)->first();
})->middleware("auth:api");
In a tutorial from Laracast, guiding through the setup of Passport, the guider doesn't have the ->middleware("auth:api") in his routes. But if its not there, well then there's no need for authentication at all!
Please, any suggestions or answers are more then welcome!
You have to set an expiration date for the tokens you are generating,
set the boot method in your AuthServiceProvider to something like the code below and try generating a new token. Passports default expiration returns a negative number
public function boot()
{
$this->registerPolicies();
Passport::routes();
Passport::tokensExpireIn(Carbon::now()->addDays(15));
Passport::refreshTokensExpireIn(Carbon::now()->addDays(30));
}
Check your user model and the database table, if you have modified the primary id field name to say something other than "id" or even "user_id" you MIGHT run into issues. I debugged an issue regarding modifying the primary id field in my user model and database table to say "acct_id" instead of keeping it as just "id" and the result was "Unauthenticated" When I tried to get the user object via GET /user through the auth:api middleware. Keep in mind I had tried every other fix under the sun until I decided to debug it myself.
ALSO Be sure to UPDATE your passport. As it has had some changes made to it in recent weeks.
I'll link my reference below, it's VERY detailed and well defined as to what I did and how I got to the solution.
Enjoy!
https://github.com/laravel/passport/issues/151
I had this error because of that I deleted passport mysql tables(php artisan migrate:fresh), php artisan passport:install helps me. Remember that after removing tables, you need to re-install passport!
I had exactly the same error because I forgot to put http before the project name.
use Illuminate\Http\Request;
Route::get('/', function () {
$query = http_build_query([
'client_id' => 3,
'redirect_uri' => 'http://consumer.dev/callback',
'response_type' => 'code',
'scope' => '',
]);
// The redirect URL should start with http://
return redirect('passport.dev/oauth/authorize?'.$query);
});
Route::get('/callback', function (Request $request) {
$http = new GuzzleHttp\Client;
$response = $http->post('http://passport.dev/oauth/token', [
'form_params' => [
'grant_type' => 'authorization_code',
'client_id' => 3,
'client_secret' => 'M8y4u77AFmHyYp4clJrYTWdkbua1ftPEUbciW8aq',
'redirect_uri' => 'http://consumer.dev/callback',
'code' => $request->code,
],
]);
return json_decode((string) $response->getBody(), true);
});
I am using Silex and apache. I want to disallow access for anonymous users to localhost/admin page. I read docs, docs of SimpleUserProvider and create the following index.php:
<?php
require_once __DIR__.'/../vendor/autoload.php';
use Silex\Provider;
use Symfony\Component\HttpFoundation\Request;
$app = new Silex\Application();
$app->register(new Provider\SecurityServiceProvider());
$app->register(new Provider\SessionServiceProvider());
$app->register(new Provider\TwigServiceProvider(), [
"twig.path" => __DIR__.'/../views'
]);
$app['debug'] = true;
$app['security.firewalls'] = array(
'default' => array(
'pattern' => '^/',
),
'secured' => array(
'pattern' => '^/admin/',
'form' => array('login_path' => '/login', 'check_path' => '/login_check'),
'users' => array(
'admin' => array('ROLE_ADMIN', '5FZ2Z8QIkA7UTZ4BYkoC+GsReLf569mSKDsfods6LYQ8t+a8EW9oaircfMpmaLbPBh4FOBiiFyLfuZmTSUwzZg=='),
'daria' => array('ROLE_USER', '5FZ2Z8QIkA7UTZ4BYkoC+GsReLf569mSKDsfods6LYQ8t+a8EW9oaircfMpmaLbPBh4FOBiiFyLfuZmTSUwzZg=='),
),
),
);
$app['security.access_rules'] = array(
array('^/admin', 'ROLE_ADMIN', 'https'),
array('^.*$', 'ROLE_USER'),
);
$app -> boot();
$app->get('/', function () {
return 'Hello from Silex container.';
});
$app->get('/admin/', function() {
return "Admin page";
});
$app->get('/login', function(Request $request) use ($app) {
return "Login page";
});
$app->get('/logout/', function() {
return "Logout page";
});
$app->get('/admin/login_check/', function() {
return "Admin login check page";
});
$app->run();
As Symfony 2 docs says, if I request to localhost/admin, I should see input fields for pass and login in alert.
So when I go to 'localhost' all are right, I see correct message. But when I go to 'localhost/admin' I expect that browser will ask with alert my login and password. But it doesn't happens, I get 'ERR_CONNECTION_REFUSED Site localhost disallow connection'. In apache log I have 301 http code. Is it normal behavior that browser doesn't ask login/password with alert? If yes, what should I add to code to change that behavior?
P.S. I know that hardcoded login and password are terrible, but I am just started Silex and it doesn't matter.
I think that you get ERR_CONNECTION_REFUSED error because of redirect to https. Try to remove this redirect by changing array('^/admin', 'ROLE_ADMIN', 'https'), to array('^/admin', 'ROLE_ADMIN'),.
Remove default section from firewalls. This section is first, catches all requests and doesn't require authorization.
If you want standard alert with user/password prompt, specify http entry point instead of form.
$app['security.firewalls'] = array(
'secured' => array(
'pattern' => '^/admin/',
'http' => array(),
'users' => array(
'admin' => array('ROLE_ADMIN', '...'),
'daria' => array('ROLE_USER', '...'),
),
),
);
I have a website in Kohana 3.0.7 and I have purchased SSL certificate. I have marked the success page to which pay pal transaction details are returned with https. After the database is updated, I added following code -
$this->request->redirect('business/fnc_manage');
But this page is loaded with https and not loaded properly on Google Chrome.
If I try as following, it gives me 500 error -
header("Location:"+url::base()+"business/fnc_manage");
exit();
How can I get rid of this ? Does this mean that I'll have to ensure that all the resources loaded should be served over https ?
If yes, then I might have to change all the paths. How can I do it for HTML helpers ?
I have not tried it but I'd say changing the base_url in your bootstrap.php could help:
Kohana::init(array(
'base_url' => 'https://yoururlhere.com',
'index_file' => FALSE,
'charset' => 'utf-8',
'cache_dir' => APPPATH . 'cache',
'errors' => TRUE,
'profile' => Kohana::$environment !== Kohana::PRODUCTION,
'caching' => Kohana::$environment === Kohana::PRODUCTION,
));