I'm working on an app that uses laravel as the backend, the login form works through ajax and the frontend is loaded locally so it's a cross domain, the problem is laravel doesn't set the cookie on the client side so the user doesn't stay logged in.
I'm thinking on getting the cookie manually and injecting it on the global ajax headers for the app but I can't find how laravel converts the session id to the giant string that sets as a cookie, how can i obtain it or how can i convert the session id to the value?
You should look at the domain variable in your session.php file:
/*
|--------------------------------------------------------------------------
| Session Cookie Domain
|--------------------------------------------------------------------------
|
| Here you may change the domain of the cookie used to identify a session
| in your application. This will determine which domains the cookie is
| available to in your application. A sensible default has been set.
|
*/
'domain' => null,
Here you can set the domain to your local domain.
I ended up making a workaround, generated a random hashed token and stored as key on redis with the id of the user as value, sent it back and stored it on the local storage in the front end, then set it on the global ajax header, and the server side just calls
Auth::loginUsingid($id)
from the token value sent by the client on every request, it's messy but it works around the problem of cross domains
Related
I am looking at swapping out the session_domain in laravel to be part of the base domain like so: '.example.com'.
This is so we can persist sessions across all subdomains of the base domain as by default cookies are only persisted on the current domain
I have tested this locally which works fine, but it seems to cause issues with active sessions as the old cookie is still preserved in the users browser with the old domain. This seems to cause issues when trying to authenticate as there are now multiple session cookies (One with the old, and one with the new cookie domain path). I have to manually clear the cookies for this to work which i obviously don't expect my users to do.
I'm not keen on the idea of middleware to expire/unset these browser cookies as it just seems inefficient to run this on every request.
What would be the best way for me to clear existing browser sessions in Laravel so that when i swap the session_domain, it does not cause issues with existing user sessions?
You need to change the APP_NAME for each subdomain
Because it replaces the session,cookie with the same name on same browser with different tabs. In short if you login to one domain, it will replace the previous domain cookie. So you need to make it different for each subdomain.
If you are having multiple .env on each domain then change it explicitly if you are using one env file for different domains you need to dynamically change it. That way your cookie won't be replaced.
If you look at inside config/session.php
'cookie' => env(
'SESSION_COOKIE',
Str::slug(env('APP_NAME', 'laravel'), '_').'_session'
),
This is where your cookie name is generated if you see that in browser Application tab inside Cookies section.
In your case, it will be laravel_session cookie name
In forms authentication, after authenticating a user/password, a cookie is created and sent to client machine. Can any one answer below questions on validating cookies.
How is this client cookie validated by aspnet on subsequent request after successful login? Does aspnet compare contents of cookie with any data store?
On server, where does aspnet maintain authenticated users details to validate the cookies?
What details are placed in cookie?
The cookie set by FormsAuthentication.SetAuthCookie contains a string representation of the encrypted and signed FormsAuthenticationTicket object which in turn represents the authentication ticket that is used by forms authentication to identify an authenticated user. The ticket object is initialized with the associated user name, version number, expiration date, issue date, a boolean value on whether the ticket will be stored in a persistent cookie or not and any user-specific data. Check out the constructors of FormsAuthenticationTicket for details. Other than that the cookie typically contains properties such as its virtual path, the associated domain and whether the cookie should only be transmitted over an HTTPS connection.
1 and 2. On each request the server looks for the cookie and decrypts the authentication ticket found in it. Also, the server checks whether the ticket is still valid based on its expiration value. No comparison to and/or validation against any server-side maintained data takes place, whatsoever.
I'm looking into an "authenticated URL" type middleware for my Laravel application where a token is generated and that token relates to an authenticated user ID and the hash of a single URL. In other words, a way of viewing a session page from an e-mail without being initially signed-in, using a high-entropy token.
When the user visits the URL, for example https://www.example.com/some/url?authtoken=WDu4UQ5SQr4WGlfMYErxRy3hjdFMs02f2NqbQ7PA, the AuthenticatedUrl middleware looks up the authtoken in the database, verifies the hash of the request's URL and the stored URL match, then logs in the appropriate user ID (Auth::guard('user')->login($token->getUser())) so the page's controller can respond as normal.
That being said, I would prefer to only allow this middleware to authenticate the request itself, not the entire session. Is this possible without causing issues with an existing normal Laravel session?
I discovered the Guard::onceUsingId($id) function which does exactly this. It logs in the request without setting any related session values or cookies.
I am trying to read the cookies in Laravel5.4. So I get the cookies after successful validation with third party Authorization server. I am not making the cookies in laravel5.4, but I am reading the cookie value send to me from view/frontend. I can see the values of cookies in Chrome debugger environment as well as from PHP global variable $_COOKIE. They are all set correctly.
However, when I tried to read the same cookie using $request->cookie('key') from controller method... it shows nothing. I also tried Cookie facade to read the value and still nothing. This controller is handling a redirect route which is called by the third party oauth server and this server when it redirects to my URL, it also sets the cookies.
Am I not setting this redirect url route correctly in web.php file in Laravel5.4? This is how it is defined in web.php as below:
Route::get('login/okta/callback',
'Auth\LoginController#handleProviderCallback');
The request object is empty when I dumped the content but $_COOKIE has the data.
Laravel's cookie class encrypts and decrypts the values of its cookies (see the App\Http\Middleware\EncryptCookies middleware). When you have it look at a cookie it didn't set, it's going to try (and fail) to decrypt it.
If you've got a cookie set from outside Laravel, use $_COOKIE to work with it, or add the name of the cookie to the $except array in app/Http/Middleware/EncryptCookies.php so it isn't messed with.
I want to know session is specific with what? This is not restrict to one language. Bellow is just use php as an example.
I use php session, it works well when I use the my website domain name. To test the website in my local vmvare ubuntu on the windows OS, I change the hosts of my windows to make the DNS to my local ip. When testing local, I use domain name, it also works well. But when I change the url in the browser to Ip, the session is lost.
You may confuse why I do this, because I want to also test the page on my android device, for I cannot change my android device's hosts file without android root, so I have to use ip.
You may also confuse why I not use the ip all the way? Because I use a third open login in my web app. The third open login mast use the domain name as the redirectback url, so when I loged in, it will redirect to the url in the domain name format.
Why the php session is the same when the domain name and the ip?
To make sure php session is not the same with domain name and ip? I also tryed my admin system, upper is user system.
I also try my administration system, I can use ip to login all the way. But when I change ip to the domain name in the url, the session also lose.
Since you mention PHP, I'll include information from PHP manual.
I believe other languages behave similarly.
In the server, a session is specific to a cookie.
From PHP manual:
Session IDs are normally sent to the browser via session cookies and the ID is used to retrieve existing session data. The absence of an ID or session cookie lets PHP know to create a new session, and generate a new session ID.
In the user agent (the client, usually a browser), a cookie is specific to a domain and path.
From RFC6265, section 4.1.2.3:
The Domain attribute specifies those hosts to which the cookie will be sent. For example, if the value of the Domain attribute is "example.com", the user agent will include the cookie in the Cookie header when making HTTP requests to example.com, www.example.com, and www.corp.example.com.
Section 4.1.2.4:
The user agent will include the cookie in an HTTP request only if the path portion of the request-uri matches (or is a subdirectory of) the cookie’s Path attribute, where the %x2F ("/") character is interpreted as a directory separator.
So, if you move back and forth from domain name to IP address, for instance, example.com and 12.34.56.78,
a session cookie created by the server for example.com will not be sent back by the user agent
if you later make a request to 12.34.56.78, even if both are the same server.
With the later request, because the server sees no session cookie, a new session is created and a new cookie is sent.
That's why using both domain name and IP address will use separate sessions.
If you need to use the same session when using both domain name and IP address, you have to preserve the session ID between requests.
A common method is to pass the session ID in the query string.
PHP session management, in fact, can also be configured to use this method but I never need to use it, so I can't tell you how that's gonna go.
Continuing my example, you can use this for subsequent requests:
http://12.34.56.78/?sessionId=abcdef0123456789
Where abcdef0123456789 is an example session ID.
In the PHP code, set the session ID before calling session_start().
Example code:
if(isset($_GET['sessionId']))
session_id($_GET['sessionId']);
#session_start();
Of course, you don't have to use sessionId.
You can use foobar or anything else.
You can also change it daily or even hourly to prevent session hijacking.
Update: To use foobar, modify the PHP code to this:
if(isset($_GET['foobar']))
session_id($_GET['foobar']);
#session_start();
With that code, you can pass the session ID like this:
http://12.34.56.78/?foobar=abcdef0123456789
If you want to use xyz, the PHP code would be:
if(isset($_GET['xyz']))
session_id($_GET['xyz']);
#session_start();
You can pass the session ID like this:
http://12.34.56.78/?xyz=abcdef0123456789
The point is, it is really up to you.
The reason of this behavior is the following:
When a session is created, its session id is stored in a cookie. The value of the cookie is sent by the server in the HTTP field Set-Cookie.
At the next request from the client to the server, this session id is sent back to the server in the HTTP field Cookie. But the user agent (browser) should send the cookie only under certain conditions. Basically the domain stored with the cookie must match with the domain of the server. But in fact, the rule is much more complex and is defined in the RFC 6265 as follow:
The user agent MUST use an algorithm equivalent to the following
algorithm to compute the "cookie-string" from a cookie store and a
request-uri:
Let cookie-list be the set of cookies from the cookie store that
meets all of the following requirements:
Either:
The cookie's host-only-flag is true and the canonicalized
request-host is identical to the cookie's domain.
Or:
The cookie's host-only-flag is false and the canonicalized
request-host domain-matches the cookie's domain.
The request-uri's path path-matches the cookie's path.
If the cookie's secure-only-flag is true, then the request-
uri's scheme must denote a "secure" protocol (as defined by
the user agent).
NOTE: The notion of a "secure" protocol is not defined by
this document. Typically, user agents consider a protocol
secure if the protocol makes use of transport-layer
security, such as SSL or TLS. For example, most user
agents consider "https" to be a scheme that denotes a
secure protocol.
If the cookie's http-only-flag is true, then exclude the
cookie if the cookie-string is being generated for a "non-
HTTP" API (as defined by the user agent).
If you have not the courage to read all the RFC6265 and related RFC's, you can make some experiments in your browser and look at the HTTP headers and the stored cookies in different situations. In Firefox, you can observe this, by :
hitting CTRL+SHIFT+K
click on the network tab
reload the page
click on a request