Get user's profile data after auth with SocalNick/ScnSocialAuth - zend-framework2

I have a ZF2 project and I'm using SocalNick/ScnSocialAuth (https://github.com/SocalNick/ScnSocialAuth) to enable social authentication.
The auth flow is ok. I've already got the user to be authenticated using his or her social login (for example, Facebook).
Now I need to know how can I get access to user's profile data from my Controllers an Views. I suspect that it must be using HybridAuth module (that is also loaded), but I couldn't find out how.
Can anyone help me?

The solutions proposed by Adam Lundrigan are OK. But there is another one that I would like to let registered here.
The following piece of code can be called from a controller's action:
$hybridAuth = $this->getServiceLocator()->get('HybridAuth');
// if the user is connected, authenticate will return an instance of the provider adapter
$adapter = $hybridAuth->authenticate('facebook');
if (!$adapter->isUserConnected()) {
// do something sensible for a logged out user...
return $this->redirect()->toRoute('some-logged-out-route');
}
$userProfile = $adapter->getUserProfile();
I would like to thank Nicholas Calugar for showing me this alternative solution.

Two of the possible approaches to get access to that data at the time the user signs up:
You could attach an event listener to the registerViaProvider event, which receives the HybridAuth adapter as a parameter. The simplest way to achieve this would be to attach it during your module's onBootstrap, something like this:
$sem = $e->getApplication()->getEventManager()->getSharedManager();
$sem->attach('ScnSocialAuth\Authentication\Adapter\HybridAuth', 'registerViaProvider', function($event) {
$provider = $event->getParam('provider');
// $provider is the HybridAuth provider the user authenticated
});
Then extract the user's profile data and store it somewhere.
Another possibility is: ScnSocialAuth's HybridAuth adapter (ScnSocialAuth\Authentication\Adapter\HybridAuth) implements a <service>ToLocalUser method for each supported service, so you could override ZfcUser's entity to add some extra fields then extend the HybridAuth adapter class to override each of those methods and populate your ZfcUser entity with the necessary profile data.

Related

Deployd : Most secure, most elegant way to get all objects in a specific collection created by the logged-in user?

I think the title pretty much says it all... Brand new to Deployd, so any pointers about how best to go about this are appreciated.
To get the objects in a collection created by the user (I assume you're using the javascript library dpd.js):
// Get the current user:
var currentUser;
dpd.users.me(function(result, error) {
currentUser = result;
});
// query your collection with your currentUser id as parameter
dpd.yourcollection.get({creator:currentUser.id}, function(result) {
// Do something with the result
console.log(result);
});
Your collection should have a property "creator" that contains the id of the user who created the object (*).
Then, to secure your backend, go to the dashboard, in the ON_GET tab of your collection and secure it with this code:
cancelUnless(isMe(this.creator), "You have to be the creator to view this item", 401);
More info about cancellUnless() and isMe() here:
http://docs.deployd.com/docs/collections/reference/event-api.md#s-cancelIf%28%29,%20cancelUnless%28%29-764
The good practice to secure your collections is to allow queries only if user is logged:
cancelUnless(me,"You have to be connected to view this item", 401);
Users collections should be particularly well secured (allow ON_PUT only by admin or something like that).
*: to automatically store the currentUserId in the creator property, you could also add this in the ON_POST event in the dashboard:
this.creator = me.id;
More info here: http://docs.deployd.com/docs/collections/reference/event-api.md#s-me-764
As of version 0.8.9, event ONBEFOREREQUEST exists and you could just put this code in there:
cancelUnless(me);
query.creator = me.id;
This means that for every request sent to that endpoint, creator key would be queried to have the currently logged in user's id. If there's not currently logged in user, the request is canceled.

MVC4 How to go about using IsInRole without SimpleMemberShip

Just curious what would be the best way to do this?
used to using
if (User.IsInRole("Administrator"))
with an older program of mine,
Using the new Kendo templete( new to me ) for MVC4-VS2012 Projects it created everything w/o simplemembership, so i wrote my own login system with help of some youtube videos and documentations.
It is very flexible and works, just curious on how I can check if a user is in a Roll Via A view ( like if (User.IsInRole("Administrator")) ) would have done. And or the best way to do so ( possibly in controller )
You can continue to use User.IsInRole(""), you simply need to set HttpContext.User with the correct principal that has a list of roles.
You can create your own Authorization Attribute that would take care of this:
var websiteRoles = userRepo.GetRoles(HttpContext.User.Identity.Name);
var identity = filterContext.HttpContext.User.Identity as FormsIdentity;
filterContext.HttpContext.User = new System.Security.Principal.GenericPrincipal(identity, websiteRoles.ToArray());
Follow up:
Your GetRoles() method can be implemented any way you like, you simply need to have a list of roles that the user belongs to. You will use this list to create the Principal object to set the User to.
Using this approach will allow you to use User.IsInRole()

customize sfApplyApply or create separate module?

I'm not sure if I am approaching this the right way; looking for some input from the community.
I'm using the following pluggins:
sfDoctrineGuardPluggin //for user management
sfForkedDoctrineGuardApplyPluggin //for registration of new users
What I'm trying to achieve:
I'd like to allow my registered users to register child-users. To do this, the child-user's that they create must inherit a couple of the parents attributes (their corporate_id, employer_type, etc... in child-user's profile at bind time). Setting these attributes has been challenging, as from what I can surmise from my reasearch, the sfApplyApply form does not have setters that can be overridden.
As an alternative, I attempted to create a whole new "user" module which uses the sf_guard_user table schema. This worked somewhat, but it lost the features found in the registration pluggin (email confirmation) and it was not salting the password or something because I was never able to login a user created this way - which always produced an error saying the username or password were incorrect.
So the question is, what's the best approach to achieve my desired result?
In your action:
public function executeNew(sfWebRequest $request)
{
$this->form = new sfApplyChildApplyForm();
}
In the plugin forms, create a form called sfApplyChildApplyForm modeled after sfApplyApplyForm.
That's it.

ASP.NET MVC custom membership for beginners

I am creating my own website and blog and I want for first time just me in database (my name and password) and maybe later some registration for others but first log in just for me and administration with authorization. I don´t want to use Membership from MS. I want try to create my own from start so I am looking for guide for beginners but I found big guides with roles, rights. I want just small example with check username, password in database with log on data.
Thanks for help
Libor
Even if you don't want to use the membership and role provider data store you can still utilize the authentication. Trust me, it's a lot easier than building your own. Here's how it works:
We'll say you already have your user storage setup for retrieving the username and their password. For the sake of simplicity I'm going to pretend you have a static class called DataLayer that contains your data retrieval methods for pulling info from the database (or whatever storage you use).
First you need a way to let the user log in. So set up a page with username and password fields. Then in the action method that the page posts to set up a quick if statement:
if (DataLayer.UserExists(userModel.Username))
{
User userFromDB = DataLayer.GetUser(userModel.Username);
if (userFromDB.Password == userModel.Password)
{
FormsAuthentication.SetAuthCookie(userFromDB.Username, checkBoxRememberMe.Checked);
//Use userFromDB as the username to authenticate because it will
//preserve capitalization of their username the way they entered it
//into the database; that way, if they registered as "Bob" but they
//type in "bob" in the login field, they will still be authenticated
//as "Bob" so their comments on your blogs will show their name
//the way they intended it to.
return "Successfully logged in!";
}
}
return "Invalid username or password.";
Now that they are authenticated you can just use Page.User.Identity.IsAuthenticated in your code to find out if they are logged in. LIke this:
if (User.Identity.IsAuthenticated)
{
DataLayer.PostBlogComment(User.Identity.Name, commentBody);
//Then in your controller that renders blog comments you would obviously
//have some logic to get the user from storage by the username, then pull
//their avatar and any other useful information to display along side the
//blog comment. This is just an example.
}
In addition, you can lock out entire action methods or even whole controllers to users that are authenticated through the forms authentication provider. All you have to do is add tags like these to your action methods/controllers:
[Authorize]
public ActionResult SomeActionMethod()
{
return View();
}
The [Authorize] attribute will prevent users that are not logged in from accessing that action method and it will redirect them to your login page. You can use this same attribute to filter out roles if you are using the built in roles provider.
[Authorize(Roles="Admin, SalesReps")]
public ActionResult SomeActionMethod()
{
return View();
}
These attributes can also be added above the controller class to apply it's logic to the entire controller.
EDIT: To log a user out all you need to do is call FormsAuthentication.SignOut();
Hey #Bibo, good for not choosing the Membership providers. I think a UserService or similar which provides methods for creating, authenticating users and some few more methods should be enough. As a suggestion, use password hashing and a password salt for the user´s password. Here is a good link to look at. Also have a look at this answer I gave some time ago.
Good luck!
EDIT: The rememberMe parameter should be named keepMeSignedIn instead.
This article on forms authentication gives you loads of info for creating your own simple security system, especially the bit about FormsAuthenticationTicket.
http://support.microsoft.com/kb/301240

Where to store common action parameter data in asp.net mvc application

Our web application needs one common parameter in every action method.
In our case it is the customer account id and we need to support the following scenarios
a. A group of users might have the same account id which can be derived from the user profile.
b. Customer Support team should be able explicitly supply the account id of a customer and also should be able to switch the account on any page
We are trying to not to use asp.net session to store this kind of data.
Are there any other options to store and manage this kind of common parameter data?
Write it out as an ecrypted value to hidden field on your master page and supply the value to every view. When the user is in a a customer role, place a change account "control" on the page that is able to retrieve and update the account data -- via AJAX, perhaps -- to change the current account id. It might be easiest to do this with a custom base controller which gets the data via the ValueProvider directly and stores it as a property on the page rather than having it be a parameter to every method.
Use Routing for the value. So if you need to change the id you can use another URL or post it as a parameter.
Whenever you need the value just ask the ValueProvider for it.
In case it is blank - use the one from user profile.
Of course you'd better write small method that will do just that:
// Register route like:
route.MapRoute("ProvidesAccountId", "{controller}/{id}/account{accountId}/{action}.aspx")
// Property on the base controller
protected Account CurrentAccount {
get {
var accountId = ValueProvider.GetValue<int?>("accountId"); // GetValue is just a helper
if (accountId.HasValue)
return YourRepositor.GetAccountBy(accountId.Value);
return CurrentUser.Account;
}
}
Not to use current user's account hit the URL: Profile/123/account/Edit.aspx
To use another account you can hit the URL: Profile/123/account-456/Edit.aspx
You get the idea.
Cheers,
Dmitriy.

Resources