I have two Symfony applications. They point on the same database for sharing some tables.
So one user can login into app1 and app2 with the same username and password. But the session is blocked for the app is logged in. I'm using FosUserBundle.
My question is, how to share the session to the differents apps ?
I tried to add in the config.yml this line on the two apps :
framwork:
session:
cookie_domain: .my-domain.com
name: SFSESSID
Indeed app1 is available on app1.my-domain.com and app2 is available on app2.my-domain.com
Second possible answer is to listen login event and perform login when i view session of my second app. Right ?
Thanks.
Unfortunately it won't work in this way, because user will have your cookie only on one of domains. You can create an API to share information about that if user is logged in and recognize who he is, but the right way to do this is creating third application - Single Sign On which will be purposed only, and only to login and authorize user. Your two current apps will always authorize and authenticate user with SSO.
To implement this you can use https://github.com/FriendsOfSymfony/FOSOAuthServerBundle/ as a server and https://github.com/hwi/HWIOAuthBundle as Clients.
Or, if you want to do this really quickly but messy you can create a JS script which will call the second page and create own cookie there. But if somebody asked you I haven't recommended you that.
Piotr
Related
I'm building an SAAS with a single database. Tenant in this case is called site.
I want to achieve what Stackexchange does where it has a global login as well as a stackoverflow/softwareengineering/etc login. I'm not sure how to store users. A user can have many sites and sites can have many users. The problem with designing a JoinTable is that the user roles are stored in the User table (im using Symfony3.4). I want separate roles per site/tenant.
Another problem I'm trying to figure out is how to go about logging in. I'm using oAuth2 and to login in I sinply call {{url}}/oauth/v2/token?grant_type=password&client_id=client_id&client_secret=client_secret&username=admin&password=pass. How should I make the user log in to a specific tenant/site? Do I add site_id to the query parameters?
Thanks for reading.
This question is very broad, so I'll take a stab at it.
If you are building out a network of sites, each site would ideally have it's own database. This will ensure sandboxing and the ability to easily migrate a site to it's own infrastructure if needed due to scaling or security concerns.
When dealing with user authentication, it sounds like you'll want a single secure user store that acts as the oauth2 server and each of the sites act as a Oauth client. You'll want to use the Authorization Code flow grant type in OAuth.
Essentially, a user visits Site A. Site A sees they are not logged in via the site's session. It redirects to your OAuth server which shows a login (think of the google login). Since Site A also passed in a callback url, once you've signed in, the OAuth server knows where to redirect the user, along with the valid token information. Then Site A takes that token and exchanges it for an access token on the server-side so now you've got authentication data on Site A.
If you are going to implement your own OAuth handshaking, you should utilize an existing server/client library. For PHP, you can look at the League OAuth server library, or use Laravel Passport, if you're using Laravel. There are other similar packages for other frameworks out there.
I have this app that uses data from gmail accounts. I have been able to create a php site that retrieves the oAuth tokens (online and offline) and later the necessary user information from the mailbox, all using the Google php api. Now to my problem:
When a secondary user logs into gmail in a browser that was previously used by an authorized user, the credentials seems to "stay". So the 2nd (or 3rd or nth user) can see data non-related to them, which is also a security hole. But most important: every loged in user into gmail is seeing only the data of the 1st logged in user.
The question: Is there a way I can use Google PHP API or Google JavaScript API to retrieve the user name of the current gmail session?
This is the current php piece of code I've been using to retrieve the user data:
use google\appengine\api\users\User;
use google\appengine\api\users\UserService;
session_start();
$user = UserService::getCurrentUser();
$userEmail = htmlspecialchars($user->getEmail());
The idea is that the app uses the current gmail user information to query a database and then retrieve the data for that specific user - and only that logged in user. If the user is not authorized, then prompt for the authorization window and ask for permission.
Any ideas or suggestions are welcome.
UPDATE (Sept 7, 2015):
I have made a change in the app.yaml so every logged in user in gmail gets served a different uri from my app. That works just fine. Now I face a new issue: how can I make the PHPSESSID and SACSID cookies to use an specific path instead of the whole domain? That way - theoretically - I can have several logged in users each and every one connecting to a different subfolder.
I've read the whole documentation about the UserService but it seems all I can do is redirect to this:
UserService::createLoginURL($_SERVER['REQUEST_URI']);
And that takes care of the authentication.
The question: How can I restringe the scope so the cookies gets the appropriate folder path?
The main issue is that once you log in to App Engine (via the UserService), that a user session has now been created in your App Engine application, and therefore it doesn't really matter what you do in GMail or any other Google application, as the session has already been created, and persists within your application.
The App Engine UserService was available way before secondary logins were even possible, and it hasn't been updated since. So this use case probably wasn't a consideration when the API as developed.
I want to create a common logins for my php applications. My website has four and more php applications. I want to create a common login for these php applications in the same way as google uses common login for its apps. My website is new and has not be indexed much. Can I create a common login for users to use my website apps. Is it simpler and possible.
My website :http://goo.gl/d2n20q
You can. It's called Single Sing-on (SSO), there should be A LOT information about how to implement it on the web. Here's one on PHP that you could use and customize: http://www.jasny.net/articles/simple-single-sign-on-for-php/
If it's cookie based auth (you authenticate the user, then save a cookie with the user auth info), you will need to take the domain into consideration, that is all web apps should have the same domain i.e. www.finysel.com, app1.finysel.com, otherapp.finysel.com (and set the cookie accordingly).
An easy approach is just create a database/table for logins, then share common files for auth thru your PHP sites include /Path/to/shared/Login/login.php.
You can also create a web service that takes the login information and returns if the auth is valid and the auth info required. An easy way is just to implement it with JSON responses (if the user and pass are valid, then you return the User in JSON, if the user is undefined then it didn't authenticated successfully), then you can create just one Ajaxy Login that you can re-use in all your websites.
Note that SSO just Authenticates the user. To check for privileges and permissions you would need to add Authorisation layer.
Finally, PHP has an oAuth module that you could use if you decide to implement a full fledged service. You can become your own oAuth provider. That's how you'd go if you want an implementation like the one provided by "Sign with your Google/Facebook/Twitter/OpenID Account" but might be overkill for what you need.
create a database dedicated to users, and authenticate users against this database on all apps.
[Scenario]
I already have 5 PHP5.3+ applications (eg: App-A, App-B, App-C, App-D and App-E) up and running. Here, each application has its own login user-id and password.
[New Requirement]
Now, I want to implement the single user-id and password to login to all these applications (by using App-A). Lets say: I want to login to App-A as usual and once login I should be able to click through to other application (B,C,D and E) by simply clicking on the icon on App-A (once login).
And, my user should not be apple to login through App-B or C or D or E. They always need to connect via App-A.
[Background]
-All of these application are running on different domain but on the same server.
-Admin will be able to enable/disable certain App for certain user
Does anyone has done similar or anyone has any suggestion please suggest.
This is the very good question and have done small research on your question on different ways:
OAuth:
After reading the documentation and gone through many service providers it is not possible. Oauth service provider gives the consumer key and secret and they check the request coming from the domain and thus if the same oAuth consumer key is used on different domain Names that doesn't work.
Setting Cookie Multiple domains
Simply, it is not possible to set the cookie without visiting the domain by any means
Thus, I can say that it is not possible to set cookie or use the same consumer key and secret for multiple domains
Alternative ways
Use HTML5 Web Storage for storing the information and then accessing
the information from different domains is possible.
Use AJAX/CURL for sending the request for setting the cookie for different domains such as example.com/session_cookie.php?info=xxxxx
Maintain a single sub-domain/page for all the domain for login purpose for across all the domains.
I am writing an application in CodeIgniter and I have concluded that it's best to write two applications. One for back office and one for client use.
I would like to have just one login screen. It will be in the back office application but if a client user logs in then I want to redirect to the client app and create a session there. The database user table stores the user type i.e. client or admin.
I have come up with the following solution. As I want to this the correct way I said i'd run it by you guys to see what ye think.
User logs into admin CI app.
Admin CI app verifies user and determines type. If admin then go ahead and create session etc.
If the user is a client then MD5(user_ip+timestamp OR make a secure token some other way) and store in a token field (user_table) in DB.
redirect the user to the client admin via a login page. The paramters would be the token and username. The login function would then go to that user in the database and verify the token.
On successful authorization of token the CI client app would start a session and let the user in.
This seems like a very long winded method. Ideally there would be a way to start a session for one CI app from another?
Any ideas?
Thanks.
Once you've verified admin or client, I would use the CodeIgniter session class with the ci_sessions table in your database.
http://codeigniter.com/user_guide/libraries/sessions.html
Then to distinguish users from client or employee add a variable to the session.
$this->session->set_userdata('user_type', 'client');
Then just use that if ever you need it.
I would go about making 2 applications under HMVC (Hierarchical-Model-View-Controller) framework.
HMVC CodeIgniter Tutorial
Then you can go about using same sessions under multiple applications, as well as use the same models for user management, etc..
HMVC helps you modularize your applications, thus if you want to add more applications in the future, you can easily do that, passing over same sessions and such.
I answered your question in a bigger scope, one central login with 2 apps, best should be done with HMVC.
:)
Might wanna check out BackEndPro for CodeIgniter, could save you a lot of time.
Includes:
User Authentication with registration & account activation
User Permissions by using ACL (Access Control Lists)
Admin GUI backend for editing Site-wide Preferences
Built on Matchbox (for Modular development)
Asset Library (optimize, cache, and load JS & CSS)
ReCAPTCHA
Status messages (info/success/warning/error messages for the user)