Hi I am working on a web2py project.
I use auth object to create login feature
And using the following code
auth.settings.extra_fields['auth_user']= [Field('address')]
So whenever, an user sign up for an account, the person need to put address.
What I would like to do is display the address in default/index.html when the user login to my application.(the user can view his own address only, not the others)
Do I need to deal with db.auth_user??
I have no clue...
Can you help me?
Thank you.
If the user is logged in, the entire user record is available in auth.user (which will have a value of None if the user is not logged in). So, to display the address in a view:
{{=auth.user.address}}
You could also retrieve the user record from the database via db.auth_user(id) or db(db.auth_user.id == id).select().first(), but using auth.user is more efficient, as it is stored in the session and therefore does not require a database query.
Related
Newbie to Parse Server here.
I have an app which reads data from Parse Server and displays it to users without logging them in.
I want to create another 'Admin' app which will allow ONLY ONE pre-populated admin user to login and change the data. Is this possible via Facebook login? I would prefer Facebook login because with normal (user, password) login I can't implement 2FA easily on Parse Server. Facebook login would take care of the issue since the user is already logged into Facebook using 2FA.
Is this possible? Any suggestions / pointers would be appreciated. I am coding both apps in React Native. The first app is complete.
The type of login has nothing to do with the abilities a user has. The simplest solution for your desired setup is using class-level permissions:
create a new Role object and name it accordingly, e.g. admin
add your admin user to that role
set class-level permissions for your data classes: grant public read access, limit write access to the admin role
Now every user can see all the data, but only members of the admin role are able to manipulate them. If you want you can add more users to the role to also give them write access.
BTW: all these steps can be performed in Parse Dashboard, no coding required.
EDIT
Actually you can have it even simpler, the class-level permissions can also be granted to a single user -- so no need for a role, if you really only need one admin.
I am brand new to Visual Studio 2012 and MVC 4, and I've been working with the SimpleMembershipProvider via the WebMatrix.WebData library.
I'd like to integrate Facebook as an external login source down the road, but it's not a requirement as of right now. However, to get a decent feel for what it would take, I've been following the tutorial and guide found here - http://www.asp.net/mvc/tutorials/mvc-4/using-oauth-providers-with-mvc.
My question :
If a user has already been created using :
WebSecurity.CreateUserAndAccount(model.Email, model.Password);
WebSecurity.Login(model.Email, model.Password);
Can they be "upgraded" to an oAuthMemebership account in the future, if they choose to use their Facebook credentials instead of the email and password they created when first signing up?
I couldn't find a clear answer to this question in the guide, or elsewhere, so I'm hoping someone can clarify how that process may work.
The SimpleMembership setup allows for a local and multiple OAuth logins all sharing the same UserProfile - so a single user can login with either a local password, or FacebOogLiveWitter.
(I should state, that I'm assuming in this answer that the OAuth provider does not send back a matching piece of information for a local account. If they do then the principles of actually performing the merge are the same, but the complexity and steps are vastly reduced.)
The OAuth registration process will refuse the user if they use an existing user name, rather than try and merge two accounts. Therefore this isn't simple, you'll have to build the functionality yourself. The process is complex as there are many directions the user can approach this from (so you could simplify by only supporting one or two), and you need to enforce security as well in case someone tries to merge into an account they don't own.
I will assume you are comfortable with the link you've posted, and you've followed the Facebook help at (for example) Facebook Login and The Login Flow for Web (without JavaScript SDK) so you have a working test application.
Your general process has to have multiple user journey approaches to make sense to a user:
for a logged in user (with a local account)
let them login to facebook and associate the accounts
let them merge an existing account on your site which uses a facebook login
for a logged-in user (with a facebook account)
let them create a local account
let them merge an existing local account on your site
for a non logged in user who tries to register a local account
let them merge this new account with a facebook login that is already registered, and do that as part of the registration process
for a non logged in user who tries to register (or log in for the first time with) a facebook account
let them link this with an existing local account as part of the registration process
etc.
ASK PERMISSION
(You can skip this if the OAuth provider has sent back a matching identifying piece of information, such as an email address).
You should enforce confirmation security, usually through email confirmation sent to the target account of the merge. Otherwise:
someone can login to your site with facebook for the first time
during that process say they "own" the email address or username of a local account (remember, facebook won't necessarily confirm what their email is for you)
and therefore gain access to the existing local account
So, once the merge "request" is made, you need to ask for permission to proceed from the target account of the merge.
The MVC 4 AccountController
I will use Facebook as our OAuth example. To compare what happens when you register a user on your local authentication framework vs. OAuth:
Local: creates an entry in webpages_Membership and an entry with the same UserId in UserProfile (assuming you are using the default tables for the MVC 4 application template)
OAuth: creates an entry in webpages_OAuthMembership and an entry with the same UserId in UserProfile
Now let's look at what happens when a user signs in using Facebook for the first time:
They click on Login using Facebook (or whatever your button says)
they get taken to facebook to login
they succeed (let's assume that, and ignore the failure case)
they then get sent, invisibly to them, to /Account/ExternalLoginCallback
OAuthWebSecurity.SerializeProviderUserId is called, passing the OAuth details to that Action
They get redirected to /Account/ExternalLoginConfirmation and asked to provide a username for their new presence on your site
If that user name is available then UserProfile and webpages_OAuthMembership entries are created
This process is your chance to "join" the accounts by matching some unique piece of information. As long as you end up with the same UserId in UserProfile, webpages_Membership and webpages_OAuthMembership you should be ok. So we have to intercept the process at the point of /Account/ExternalLoginConfirmation.
If the OAuth provider has sent back a matching identifying piece of information, such as an email address, this becomes simple, test for this in the ExternalLoginConfirmation action, and auto-merge using a similar process to the one outlined below.
However, I think you can't/shouldn't assume that the user uses the same email address for your site and OAuth, (nor should you for many reasons). Also, probably in the T&Cs for something like FacebOogLiveWitter it stops you asking for the email of their account anyway, and if they don't currently they might in future.
So instead, you could link the accounts based on alternatives, like username or email address, or phone number. Either way you are going to need them to input some identifying piece of information that is unique against an account, and will pull back the target account.
Wrapping up
So to put this all together: In the first part of this answer I outlined how you will need to consider multiple user journeys to merge accounts. I will use the example 4.1.
Your process will need to:
(Assumption - when a user first registers with a local account, you ask them for an email address and validate it or assume it is valid)
Let the user login with facebook for the first time
at Account/ExternalLoginConfirmation ask them if they want to
Create a new account with you
Use their facebook login to access an existing account
Assuming the latter, then you log a request in a new table (maybe "MergeAccountRequests") with:
The facebook account UserId
The target merge local account UserId
An authorisation code to use in the email you need to send
(From this point on, if they login without confirming that merge, they will have to get sent to a page to ask them to confirm, rather than create objects in other db tables which you have to worry about later)
You then send an email to the address of the target merge (local) account asking for permission to complete the merge (a standard confirmation email, with a link)
When they click on that link, or enter the code you sent them (you could use SMS as well as email) then you need to merge the two accounts
Choose the "new" and "target accounts (in this case "new" is the facebook account as you don't have data associated with it yet)
Delete the UserProfile of the "new" account
Change the UserId of the "new" account webpages_OAuthMembership table to the same as the "target" account
Log the user out (so there are no complications depending on which account they are currently logged in with)
Display a message to the user telling them the merge is almost complete and that they can now log in with either account to confirm and complete the merge
Rather than send them to a login page, i would give them the login options alongside the confirmation message.
I have a unique user creation flow which is as follows:
User comes to my site for the first time and they click a button.
I create a User in the DB for them and set a localStorage key with the UID.
Use goes about creating data and I save the data in the DB and associate it with the UID.
User comes back, and if they have UID set in localStorage, I show them the data they previously created.
User can click Register to create a "real" account from which point they will have to login with username and password or another service (e.g. Facebook).
So, how would I accomplish this with Meteor Accounts and the User model?
In a nutshell:
I need to create User mongo document with no information (about the user).
I need to authenticate a user by just having a UID (acting as a "password").
Register onCreateUser to add an "anonymous" field ({anonymous:1})
when a random password is used, maybe generated with Meteor.uuid().
Add a timestamp field
({created:new Date()}) to clean out old, anonymous accounts.
Perform old anonymous user maintenance, like deleting anonymous users more
than one hour old:
Meteor.autorun(function()
{Meteor.users.find({anonymous:1,$where:"new Date() - this.created >
360000"}).forEach(function (user) {
Meteor.users.remove({_id:user._id})}});
On the client:
Always prompt
for a "nickname." This will become the official username, or will
sit in the system forever used.
Check if client is logged in. If
not, create a user with nickname and a "magic number" password,
which logs you in. When they click register, write "Register" at the
top, but actually just change their password and $set:{anonymous:0}
Don't use localStorage, and don't use UIDs. The session cookie IS your UID.
I don't know how to help with the authentication, but as for creating a blank User object, I've successfully done the following on the server-side (with a different name...):
Meteor.users.insert({profile: {name: 'Oompa Loompa'}, foo: 'bar'});
Here is the scenario. I have two objects Users (with username/password) and UserInfo with rest of the data related to user. The Users is an old table with thousands of records and UserInfo is fairly new. I want to get as much UserInfo as I can when the user first logs in.
I'd like to force user to a custom screen after first login and ask for the UserInfo data. Once I get the "required" data in the new screen, I dont show it till the user voluntarily wants to fill in the data under "Profile".
Since there are multiple entry points to the application, I dont want to update all the controllers to check for this.
Is there a way I can use a Spring Security filter or something which is executed on successful login? I had a look at ApplicationListener<AuthenticationSuccessEvent> but it doesnt solve the problem as if I copy paste the link in the browser, it lets me go ahead to the destination without asking for "extra information".
In a nutshell, I want a check after each login which, if fails, user is not allowed to enter the application. No matter how he tries to get in.
In your Config.groovy, configure Spring Security's defaultTargetUrl and tell it to always redirect there:
grails.plugins.springsecurity.successHandler.alwaysUseDefault = true
grails.plugins.springsecurity.successHandler.defaultTargetUrl = '/userInfo/edit'
In your UserInfoController's edit action, you can check that the required fields are present (userInfo.validate() perhaps?) and if they are, redirect to wherever you like, perhaps '/', otherwise render the edit info view.
You can adopt what #doelleri proposed and enhance the rule by those steps:
run a batch task to assign a temporary ROLE_DISABLED role to each user who does not provide supplemental information yet. If the user already had some roles, save them in some property.
setup your authorization rule as that users with ROLE_DISABLED role only allowed to access /userInfo/edit.
in /userInfo/edit, if the user has a ROLE_DISABLED role, render the information input view, and resume user's role after it successfully updated its information. Otherwise redirect to '/' or the path it requested.
I am trying to create a project that involves two roles say admin and student is it Ok to provide two radio button and then checking out which role a user select and then upon selection perticular page is constructed ??
Is my approach wrong ? what would you suggest??
Why ask for the user to choose a role? based on the role, load the page.
Your application must be simple to navigate through. Try to minimize the user interaction as much as possible. Wherever you can calculate the users need, do it. Here, provide a login page with a username and password entries only. You can then check whether that user exists in the database. If yes, check which role he belongs to, and redirect him to the page corresponding to his role.