7

Dears, I created a custom REST API, So customer can login Via facebook and twitter through mobile app. The API consists of one service which take some parameters and email parameter and check if this email is found or not.

-If found, then return customer id.

-If not found, then insert email and other parameters (firstname, lastname, socialid, socialtype).

My question, I don't save password for the customer because the response return from facebook doest not contain password, so how to get token authentication, so I can do all operations which request customer token?

In normal, I can login and get token through:

POST

 https://domain.com/index.php/rest/V1/integration/customer/[email protected]&password=12345

and response will be token.

3

3 Answers 3

7

What I understand from you question is, You have only email (and obviously some network specific secret key to validate i.e facebook key).

So You just need to load the customer by email id as below.

protected function getCustomerToken($emailId){
 /**
* @var \Magento\Customer\Model\Customer $customer */
*/
$customer->loadByEmail($emailId);
if($customer->getId()){
        /**
        * @var \Magento\Integration\Model\Oauth\TokenFactory $tokenModelFactory 
        */
        $customerToken = $this->tokenModelFactory->create();
        $tokenKey = $customerToken->createCustomerToken($customerId)->getToken();
        return $tokenKey;
}
return "YOU MSG FOR CUSTOMER NOT FOUND";
}

The above code should return the token key without password.

Note: Make sure you are doing proper & strong validating before generating the token & rest is already explained in Franck's answer .

3
  • hi, i am getting this error message in response { "message": "A customer website ID must be specified when using the website scope." }
    – Ashar Riaz
    Commented Dec 27, 2017 at 12:21
  • @AsharRiaz the problem is Magento\Customer\Model\ResourceModel\Customer::loadByEmail, here its checking if website is associated with customer. May be the time customer was created account scope was global and later changed website. Commented Dec 28, 2017 at 5:49
  • @MohammadMujassam i resolve this issue by adding $customer->setWebsiteId(1); before loadByEmail method
    – Ashar Riaz
    Commented Dec 28, 2017 at 10:43
2

I think you need to pass the Facebook auth token in order to validate your customer.

Extend the native token authentication with your logic to validate the Facebook token.

Usefull information: https://stackoverflow.com/questions/4623974/design-for-facebook-authentication-in-an-ios-app-that-also-accesses-a-secured-we

The same approach can works with Twitter.

Extend or create your own API endpoint in order to manage FB / Twitter Login.

The native code for token generation is located here :

vendor/magento/module-integration/Model/CustomerTokenService.php:74

/**
 * {@inheritdoc}
 */
public function createCustomerAccessToken($username, $password)
{
    $this->validatorHelper->validate($username, $password);
    $this->getRequestThrottler()->throttle($username, RequestThrottler::USER_TYPE_CUSTOMER);
    try {
        $customerDataObject = $this->accountManagement->authenticate($username, $password);
    } catch (\Exception $e) {
        $this->getRequestThrottler()->logAuthenticationFailure($username, RequestThrottler::USER_TYPE_CUSTOMER);
        throw new AuthenticationException(
            __('You did not sign in correctly or your account is temporarily disabled.')
        );
    }
    $this->getRequestThrottler()->resetAuthenticationFailuresCount($username, RequestThrottler::USER_TYPE_CUSTOMER);
    return $this->tokenModelFactory->create()->createCustomerToken($customerDataObject->getId())->getToken();
}

Then you can modify the validation logic and the Magento customer ID retrieval in order to return a generated token.

7
  • Thank you, Do you mean I call facebook auth token directly. As Ex, to get customer info, I call API : https://domain.com/index.php/rest/V1/cus tomers/me and Header Params: Authorization Bearer {{facebook auth token }} ??
    – Jsparo30
    Commented May 22, 2017 at 10:44
  • Not really. You can call the integration/customer/token API with username / FB token. Then extend the native call to check if the FB token is valid for this user. (FB user ID / FB token). If valid, then generate a native M2 Auth token for this user. Then use the M2 native token for the other native M2 API call. Commented May 22, 2017 at 10:52
  • Can you explain more with example? .. For integration/customer/token API with username / FB token which username ? magento 2 or facebook? .. Give more calarification for this part Then extend the native call to check if the FB token is valid for this user. (FB user ID / FB token).
    – Jsparo30
    Commented May 22, 2017 at 11:01
  • You need to create your custom API, retrieve the native code for integration/customer/token. Put your own logic to validate the FB login, then try to match the internal Magento customer and generate the Magento 2 token. Usefull native code here : \Magento\Integration\Model\CustomerTokenService::createCustomerAccessToken Commented May 24, 2017 at 12:56
  • Open new question to have specific information about Magento 2 Commented May 27, 2017 at 9:30
0

If user is loggined

<?php


namespace Test\Module\Controller\Test;

use Magento\Customer\Model\Session;
use Magento\Framework\App\Action\Context;


class Token extends \Magento\Customer\Controller\AbstractAccount
{
    /**
    * @var \Magento\Customer\Model\Session
    */
    protected $_customerSession;

    public function __construct(
        Context $context,
        Session $customerSession,
        \Magento\Integration\Model\Oauth\TokenFactory $tokenModelFactory
    ) {
        $this->_customerSession = $customerSession;
        $this->_tokenModelFactory = $tokenModelFactory;
        parent::__construct(
            $context
        );
    }

    public function execute()
    {
        $customerId = $this->_customerSession->getCustomer()->getId();
        $customerToken = $this->_tokenModelFactory->create();
        echo "Customer-token=> ".$tokenKey = $customerToken->createCustomerToken($customerId)->getToken();
    }
}

If you need login without enter password

class AutoLoginManagement implements \Flo\Core\Api\AutoLoginManagementInterface
{

    protected $_customer;
    protected $_customerSession;
    protected $_tokenModelFactory;

    public function __construct(
        \Magento\Integration\Model\Oauth\TokenFactory $tokenModelFactory,
        \Magento\Customer\Model\Customer $customer,
        \Magento\Customer\Model\Session $customerSession
    )
    {
        $this->_customer = $customer;
        $this->_customerSession = $customerSession;
        $this->_tokenModelFactory = $tokenModelFactory;
    }

    public function postAutoLogin($data)
    {

        $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
        // Load customer
        $customer = $objectManager->create('Magento\Customer\Model\Customer')->load($data['customer_id']);

        if(! $customer->getId()) {
            return 'Not Found';
        } else {
            // Load customer session
            $customerSession = $objectManager->create('Magento\Customer\Model\Session');
            $customerSession->setCustomerAsLoggedIn($customer);

            $customerToken = $this->_tokenModelFactory->create();
            $tokenKey = $customerToken->createCustomerToken($customer->getId())->getToken();
            return $tokenKey;

        }

    }

}    

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.