4

I am building an Android Application using opencart as my backend.

I want login/registration to be otp based ( no password needed ever). I know how to send sms to user and verify phone number. I am also collecting user email and Name.

I need to understand how can I register a user without password and then also make login work without password?

ashfaq.p
  • 5,379
  • 21
  • 35
  • Your best bet here is to look at the Account controllers and modify them along with the Account models. You might also want to look at subscribing to relevant Events as you can trigger a controller method on events. Assuming you're familiar with PHP & MVC, is there anything specific that you need help with? – Daniel Apr 22 '20 at 10:08
  • @Daniel I am trying to understand how it works, for eg. if I remove the check for password and get a user based on mobile no from database, then someone can just make a api call with some mobile number and he will get the user information. This sounds like a security issue to me. Any comments on this? – ashfaq.p Apr 23 '20 at 04:52
  • In order to use the API, from my limited exposure, you have to authenticate in order to get a token which then serves to authenticate each subsequent request. You also need to have an api user configured on the site. – Daniel Apr 23 '20 at 09:45
  • @Daniel I have api user, and i can generate token also which can authorize subsequent requests, but in order to attach a token with a user, i need to make the user login with email and password, however i do not have the password – ashfaq.p Apr 23 '20 at 09:57
  • What's the architecture of your app? Does it rely 100% on Opencart or do you have your own API for other aspects of the app? – Daniel Apr 23 '20 at 10:06
  • @Daniel I am using https://opencart-api.com/product/shopping-cart-rest-api/ for the REST API but yes ultimately its all connected to only opencart – ashfaq.p Apr 23 '20 at 10:08
  • I think you should have a layer between your App and Opencart otherwise you're going to have to overcome these issues including whitelisting the IP addresses. This also adds a layer of protection as your intermediate service will act as a middle man and you can set a single API user with a single whitelisted IP. Then you have much less of a challenge as your service will be implemented however you're comfortable and you will just consume the default OpenCart API without customising too much – Daniel Apr 23 '20 at 11:56

1 Answers1

1

All registration process in opencart are in model: catalog/model/account/customer.php function addCustomer

$this->db->query("INSERT INTO " . DB_PREFIX . "customer SET customer_group_id = '" . (int)$customer_group_id . "', store_id = '" . (int)$this->config->get('config_store_id') . "', language_id = '" . (int)$this->config->get('config_language_id') . "', firstname = '" . $this->db->escape($data['firstname']) . "', lastname = '" . $this->db->escape($data['lastname']) . "', email = '" . $this->db->escape($data['email']) . "', telephone = '" . $this->db->escape($data['telephone']) . "', fax = '" . $this->db->escape($data['fax']) . "', custom_field = '" . $this->db->escape(isset($data['custom_field']['account']) ? json_encode($data['custom_field']['account']) : '') . "', salt = '" . $this->db->escape($salt = token(9)) . "', password = '" . $this->db->escape(sha1($salt . sha1($salt . sha1($data['password'])))) . "', newsletter = '" . (isset($data['newsletter']) ? (int)$data['newsletter'] : 0) . "', ip = '" . $this->db->escape($this->request->server['REMOTE_ADDR']) . "', status = '1', approved = '" . (int)!$customer_group_info['approval'] . "', date_added = NOW()");

All login proccess in opencart are in library system/library/cart/customer.php function login

if ($override) {
        $customer_query = $this->db->query("SELECT * FROM " . DB_PREFIX . "customer WHERE LOWER(email) = '" . $this->db->escape(utf8_strtolower($email)) . "' AND status = '1'");
    } else {
        $customer_query = $this->db->query("SELECT * FROM " . DB_PREFIX . "customer WHERE LOWER(email) = '" . $this->db->escape(utf8_strtolower($email)) . "' AND (password = SHA1(CONCAT(salt, SHA1(CONCAT(salt, SHA1('" . $this->db->escape($password) . "'))))) OR password = '" . $this->db->escape(md5($password)) . "') AND status = '1' AND approved = '1'");
    }

Parametr $override is used for login without password from admin panel by token.. Token are one-time and are cleared after login..

Some code about this proccess are in controller catalog/controller/account/login.php

if (!empty($this->request->get['token'])) { 
.....
$customer_info = $this->model_account_customer->getCustomerByToken($this->request->get['token']); // find customer by token

You can use some hash from user device as password, this solution will be more secure than login with not encoded otp password... You may use otp password only for verify phone number

UPDATE: You can generate user token in application, than update opencart db from application with request: "UPDATE " . DB_PREFIX . "customer SET token = 'token_for_user' WHERE telephone = 'user_telephone" by user telephone.. OR "UPDATE " . DB_PREFIX . "customer SET token = 'token_for_user' WHERE email = 'user_email" by user_email ... Than make GET request http://your-site.com/index.php?route=account/login&token=generated_token ... After this request user session will be created.. Email/telephone number will be needed only for token update... Login will be only by generated token, no any other data needed, as works now login from admin panel to the customer's account..

OcPh
  • 71
  • 3
  • If i use some hash from user device as password, then how will a user login from another device? – ashfaq.p Apr 23 '20 at 09:07
  • Than may be use token... as work login from admin panel now in opencart... but you must set token each time for this user before login – OcPh Apr 23 '20 at 09:11
  • How will I set token for the user? can you explain – ashfaq.p Apr 23 '20 at 09:13
  • i believe the token is set when a user logs in, how can i get the token before login ? – ashfaq.p Apr 23 '20 at 09:15
  • Send request to opencart db such as "UPDATE " . DB_PREFIX . "customer SET token = 'token_for_user' WHERE telephone = 'user_telephone" by user telephone.. OR "UPDATE " . DB_PREFIX . "customer SET token = 'token_for_user' WHERE email = 'user_email" by user_email... If you can connect to opencart db directly from application... other variant.. You must modify controller catalog/controller/account/login.php for GET request with this parametrs, modify catalog/model/account/customer.php and add function for Token modify such as examples in the start of this comment...But this variant is not secure – OcPh Apr 23 '20 at 09:23
  • Token must be set before login... Login is checked by email and token if it exists... – OcPh Apr 23 '20 at 09:25
  • "UPDATE " . DB_PREFIX . "customer SET token = 'token_for_user' WHERE telephone = 'user_telephone". to do this, from where can i get the token ?? So user will verify OTP and then I need to log him in, but from where can i get token to setup ? – ashfaq.p Apr 23 '20 at 09:27
  • generate it.. send to db... than login.. It is one-time and will be cleared after succesfull login... And you must did GET request such as http://your-site.com/index.php?route=account/login&token=user_token ... This token are searched in db and if it exists - opencart login user with this token – OcPh Apr 23 '20 at 09:32
  • so lets assume I generate a token, and a session is created, now in order to associate that session with a user, I need to login a user. and to login I need email and password. However I will not have a password as its OTP based, so how can I login a user without password? – ashfaq.p Apr 23 '20 at 09:36
  • Based on your updated answer, lets say i create the token in application, but in order to set the token with a user in db, i will still need to make an API call and that will be visible, so anyone can call this api with a token and give an email or mobile no of another person and they will be able to log in – ashfaq.p Apr 23 '20 at 10:04
  • and regarding the same flow working for admin panel, there it is fine because there is another level of security as admin has to login to do this operation – ashfaq.p Apr 23 '20 at 10:06
  • I don't see other solution at this time... without password - only by token without big modification of opencart.... other solution - big modification in register and login proccess... – OcPh Apr 23 '20 at 10:19
  • but you do see a security concern with the above approach, isn't it ? – ashfaq.p Apr 23 '20 at 10:23
  • If direct connection to db from your application (not by api) for token update - may be normal (db customer for this connection must be limited in permissions) ... If send all requests to api by visible way - security breach...But for other variants - opencart must be very modificated... – OcPh Apr 23 '20 at 10:31
  • since i want to make all this work for Android app so communication has to happen over API – ashfaq.p Apr 23 '20 at 10:35
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/212336/discussion-between-ashfaq-p-and-ocph). – ashfaq.p Apr 23 '20 at 10:35