PrestaShop - Login programmatically - mobile

I am writing a android and windows native app. The native app stores the login details as reated for mulitple other web apps, and logs them into this when browsing to them from the native app.
one of the buttons in my app open a prestashop site for a authenticated user. How can i set the username and password and log that user in to the site programmitcally, giving the illusion and user experience that he has been seemlessly authenticated and accessed to his shop.

I know this is an old question, but theres another way which i find better for the purpose.
You include the AuthController from the controllers folder, set your post-parameters and execute the postProcess() method. After this, you can check the "$authController->errors" array for errors. If it's empty - the login was successful.
Example:
public function hookDisplayHeader()
{
if ($this->context->cookie->isLogged())
{
return;
} else {
$acceptLogin = false;
if( isset( $_POST["email"] ) && isset( $_POST["passwd"] ) )
{
$acceptLogin = $this->attemptLogin($_POST["email"],$_POST["passwd"]);
}
if( $acceptLogin )
return;
die( $this->display(__FILE__, 'logintemplate.tpl') );
}
}
protected function attemptLogin($email, $password)
{
include _PS_FRONT_CONTROLLER_DIR_ . "AuthController.php";
$auth = new AuthController();
$auth->isAjax = true;
$_POST["email"] = $email;
$_POST["passwd"] = $password;
$_POST["SubmitLogin"] = true;
$auth->postProcess();
if( count($auth->errors) > 0 )
{
$this->context->smarty->assign( "errors", $auth->errors );
return false;
} else {
return true;
}
}
Edit: This no longer works with Prestashop 1.6. As of PS 1.6 $auth->postProcess() either redirects or sends the ajaxs response immediately. There is no way to circumvent this. If you want to do something after login, you have to make two ajax calls.

Basically do the same as the PrestaShop login form does, which is (for v1.5 at least):
Sending a POST request to http(s)://yourshop.com/index.php?controller=authentication with the following parameters:
email: your customer's email address
passwd: your customer's password
back: name of the controller you want to be redirected to after success (ex: my-account)
SubmitLogin: put anything there, it just needs to be true, so that the controller knows it's a login action
If it doesn't work, your version may work differently and you will have to check the network tab of your favourite developer tool, to see what kind of request is sent with which parameters.

Related

Authenticating guest/anonymous users using JWT

I'm building an SPA that a user can upload some files. The front-end is written in AngularJS while the back-end is using an API in Laravel 5.7. The authentication is implemented using the jwt-auth library.
So far I have implemented this for registered users where each user has a personal directory on the server where he/she uploads the files. The difference between the registered and the anonymous users is that the files of the anonymous will be deleted after a while.
Now, I want to do the same for anonymous/guest users (if the press the button continue as a guest). So what I tried first in the authContrroller.php side is to use something like this:
public function authentication(Request $rrequest) {
$credentials = $request->only('email', 'password');
// Guest authentication
if( $credentials['email'] === 'guest' && $credentials['password'] === 'guest' )
{
$payload = auth()->factory()->claims(['sub' => $this->createRandomDir()])->make();
$token = auth()->manager()->encode($payload);
// OR
$factory = JWTFactory::customClaims([
'sub' => $this->createRandomDir(),
]);
$payload = $factory->make();
$token = JWTAuth::encode($payload);
}
// Registered user authentication authentication
else
{
if (! $token = auth()->setTTL(60)->attempt($credentials))
return response()->json(['error' => 'invalid_credentials'], 400);
}
return response()->json(compact('token'));
}
The idea was to create a random directory and enclose it inside the payload and use it on the next requests.
But in the case of the guest, the server returns as a token an empty object. Possibly because there wasn't a user in the DB.
Another idea that I'm thinking of is to create a random user (add it to the DB) and assign to it a random directory each time a user needs to use the app as guest/anonymous. The only thing that I'm afraid on that approach is that if there are thousands of guests then thousands random users should be created on the DB.
So what do you think? Is there any other and more efficient way to handle this?
Any idea is welcomed.

force.com sites - direct link to salesforce visual force page not working

Am facing an obstacle using force.com site
a template email is used to send to portal users with direct link to some record in salesforce
example https://example.force.com/SamplePage?id=xxxxx
by trying to use refURL param half way was done as in the next example :
https://example.force.com?refURL=/SamplePage?id=xxxxx
but passing from an obstacle to facing another,now every time i click on the new link in the email i have to re-login again regardless that i just made a login.
so for the first attempt its logical to input the credentials to login to the site but i need to prevent when the session still on to re login again every time by clicking on the link from my email
my login code in Apex is as below :
global PageReference login() {
//Get refUrl
String strRefUrl = System.currentPageReference().getParameters().get('refURL');
//Get startUrl
String strStartUrl = System.currentPageReference().getParameters().get('startURL');
if(strRefUrl != null && strRefUrl != '' && ! strRefUrl.startsWithIgnoreCase(Site.getBaseInsecureUrl() )){
//Need to remove domain part because site.login() does not redirect to absolute URL
strStartUrl = strRefUrl.replace(Site.getBaseRequestUrl(),'');
}
else if (strRefUrl.startsWithIgnoreCase(Site.getBaseInsecureUrl())){
//Redirect to base URL if refUrl is empty
strStartUrl = Site.getBaseUrl() + '/LoginPage';
}
return Site.login(username, password, strStartUrl );
}

how to store login information using onsen ui?

I want to use onsen ui and angularjs to develop a hybird application, but now I meet a problem, this application cannot store user's login information, so user must login everytime after they close the application.
I use $cookies, service, and $rootScope to store user's login information, but all of them can not work at android platform.
Anyone can help me to solve this problem?
On HTML5 mobile framework like Onsenui, I suggest to use localStorage.
You can take a look at these two AngularJs modules:
angular-local-storage
ngStorage
They have very well written instructions and demo codes as references.
use this plugin https://github.com/litehelpers/Cordova-sqlite-storage or something similar to create a sqlite database. Create a table with the information you want to keep (username and password). You can create a hash of the password and store it for better security (md5 or sha1).
You can also keep the timestamp of the login and keep the user logged in for a specific interval of time, so when he opens the app, check if you are inside this interval (e.g. day, week, etc.) from the last login and if yes, log him in automatically else show the login screen again.
if (window.localStorage.getItem("rememberMe") == "true") {
$scope.userEmail = window.localStorage.getItem("userName");
$scope.userPassword = window.localStorage.getItem("password");
document.getElementById("rememberMe").checked = true;
}
else {
document.getElementById("rememberMe").checked = false;
}
if (document.getElementById("rememberMe").checked == true) {
window.localStorage.setItem("rememberMe", "true");
window.localStorage.setItem("userName", $scope.userEmail);
window.localStorage.setItem("password", $scope.userPassword);
}
else if (document.getElementById("rememberMe").checked == false) {
window.localStorage.setItem("rememberMe", "false");
window.localStorage.setItem("userName", "");
window.localStorage.setItem("password", "");
}
Hi! have a look at the above code. It stores in local storage

How do I test Cloud Endpoints with Oauth on devserver

My app uses Oauthed Cloud Endpoints and is working fine in production.
My problem is that on the local devserver, my User user is always set to example#example.com, even though I've gone through the usual auth, access code, etc etc etc and have a valid authed user.
I get that example#example.com is useful to test oauth endpoints before I have oauth working properly, but since my app is working I'd rather see the actual user there.
To be specific, my endpoint method is
#ApiMethod(name = "insertEmp"), etc
public Emp insertEmp(User user, Emp emp) {
System.out.println(user.getEmail()); // (A) log "appengine" email
System.out.println(OAuthServiceFactory.getOAuthService().getCurrentUser().getEmail(); // (B) log authed email
...
When deployed, everything is fine, and both (A) and (B) log the authenticated user (my.email#gmail.com).
When testing on my local devserver, (A) always logs "example#example.com", even though I have gone through the Oauth sequence and have a valid, authenticated user, and (B) logs my.email#gmail.com. So I can do hi-fidelity testing, I need the User to be the real authenticated user.
So in simple terms, how do I get (A) and (B) to be the same?
It seems it can't be done. I've ended up coding around it by putting the following code at the top of my Endpoint methods.
if ("example#example.com".equalsIgnoreCase(user.getEmail()) {
user = new User(OAuthServiceFactory.getOAuthService().getCurrentUser().getEmail(),"foo");
}
So now, even on devserver, the User email matches the Oauth email.
This is not so easy. You'll have to make your settings in the APIs Console. Here you will be able to add "localhost" (http://localhost/) Then you can authenticate, through Google, even though you are running you application on your localhost for development.
I have used it extensively, and it works OK
Links: https://code.google.com/apis/console/
Just remember the ID's you use here is completely independent of you appengine ID.
Took me a few hours to figure that one out.
The thing is that when you are doing the authentication in local, you are not doing it through the Google servers so authenticating your user is something that actually is not happening in local.
Google always provides the example#example.com user when you try to simulate the log in, it happens basically in all the services, like when you provide a log in through your Google Account in any web site (for instance using GWT and App Engine).
What can be different in your site if you test with your real user or you consider example#example.com user as your user?
In your endpoint API you need this
ApiMethod ( name="YourEndPointName", path="yourPath",
clientIds={"YourId.apps.googleusercontent.com"},
scopes = { "https://www.googleapis.com/auth/userinfo.profile" })
Then in the called method, you will have a User object from the GAPI.
Use this to get the actual email from the google User object like this
public myEndPointMethod( Foo foo, User user ){
email = user.getEmail();
}
I replaced the Oauth2 user (example#example.com) with user from UserFactory and it works fine. I use this method to validate user for all API authenticated API requests.
public static User isAuthenticated(User user) throws OAuthRequestException{
if(user == null){
throw new OAuthRequestException("Please login before making requests");
}
if(SystemProperty.environment.value() ==
SystemProperty.Environment.Value.Development && "example#example.com".equalsIgnoreCase(user.getEmail()) ) {
//Replace the user from the user factory here.
user = UserServiceFactory.getUserService().getCurrentUser();
}
return user;
}
Using the go runtime I have resorted to this function to obtain a User that is functional on both the dev server and production:
func currentUser(c context.Context) *user.User {
const scope = "https://www.googleapis.com/auth/userinfo.email"
const devClient = "123456789.apps.googleusercontent.com"
allowedClients := map[string]bool{
"client-id-here.apps.googleusercontent.com": true,
devClient: true, // dev server
}
usr, err := user.CurrentOAuth(c, scope)
if err != nil {
log.Printf("Warning: Could not get current user: %s", err)
return nil
}
if !allowedClients[usr.ClientID] {
log.Printf("Warning: Unauthorized client connecting with the server: %s", usr.ClientID)
return nil
}
if (usr.ClientID == devClient) {
usr = user.Current(c) // replace with a more interesting user for dev server
}
return usr
}
This will use the dev server login information entered using http://localhost:8080/_ah/login
It's not possible.
I use another endpoint to replace user_id in current session.

How to count login attempts in CakePHP

I'm developing application with CakePHP 1.3 and using its Auth component. Is it possible to count login fails in order to deactivate users account after a few unsuccessfull attempts? Is there anything like loginErrorRedirect?
How are you intending to deactivate a user if they can't login? If they login as
test#test.com FAIL
tester#test.com FAIL
test123#test.com FAIL
are you going to invalidate all these users?
To record login failures, your could add the following to your login() action in whatever controller
if(empty($this->Session->Auth) && isset($this->data))
{
if($this->Session->read('login.fail'))
{
$login_fail = $this->Session->read('login.fail') + 1;
}else{
$login_fail = 1;
}
$this->Session->write("login.fail",$login_fail);
}

Resources