📜 ⬆️ ⬇️

Authorization on sites through Z-Payment (OAuth 2.0)

image Hello, community! This article describes the Z-Payment API protocol based on OAuth 2.0, for authorizing users on third-party sites. We admit that it is always laziness to register, not to mention the fact that you have to share personal information (at least by mail), and when it needs to be done only once, then laziness is twofold. That is why Internet services with a large number of users offer the possibility of authorization on third-party resources through themselves and Z-Payment in this case is no longer an exception.

Introduction


Recently, the Z-Payment team implemented a server-based authorization mechanism based on the OAuth 2.0 protocol, which offers developers the ability to create authorization on third-party sites through the Z-Payment service and request the personal data of authorized users with their consent. This method allows you to implement secure user authentication on a third-party site.

In order to take advantage of access to this interface, you must fulfill 3 mandatory conditions:
  1. Have a registration on Z-Payment
  2. Register site
  3. The site should receive public status, i.e. published in the Z-Catalog

The main task of Z-Payment when implementing this authorization method is to provide developers with another means to create independent projects that use Z-Payment resources. A successful example is the project Exchange Exchange Z-Change
The authorization process consists of 4 steps:
  1. User transfer for authorization to Z-Payment
  2. Allowing user access to personal data. The user must consent to the provision of the requested 3rd party (you) data. If the user is not authorized to Z-Payment, then he will be asked to authorize in his personal account. After successful authorization, the user will be asked to allow access to personal data.
  3. Passing the code to the site to get the access key
  4. Getting the access_token access key by the project server to access the Z-Payment API

Now in order and in more detail


Given: site. The task is to authorize / register your users through Z-Payment.

Step 1

You need to redirect the user to authorize on Z-Payment, you can do this GET or POST request to z-payment.ru/enter.php z-payment.ru/enter.php with parameters:
client_id - a required parameter, four-digit, unique identifier of the store in Z-Payment, issued when the site is registered in the system.
redirect - a required parameter, the address to which the user will be redirected after passing authorization (the domain of the specified address must correspond to the main domain in the store settings)
display is a required parameter that indicates the type of display of the authorization page. Currently supports only page, which means - authorization in a separate window
scope is an optional parameter; this parameter is responsible for the list of requested personal data about the user. The requested data must be separated by a comma or a space.
Here is a list of possible requested data:
0f_nameName
ones_nameSurname
2m_namemiddle name
3birth_dayDate of Birth
fourgroupType of certificate
fivesexFloor
6e_mailpost office
7phoneTelephone number
eightcountryA country
9cityCity
tenbalanceWallet balance

response_type is not a required parameter; it is responsible for the type of response that we want to receive; it can take values: code — if we want to make requests from a third-party server (by default) or token — if we want to make requests from a client.
According to the above, the GET request should look like this:
')
GET: z-payment.ru/enter.php?client_id=ID__&redirect=http://.ru/login&dispaly=page&scope=f_name,s_name,m_name,phone,city,e_mail&response_type=code


Step 2

Clicking on such a link, the user will be on the page where he will be asked to give consent to provide the 3rd person (your site) with the data you request in the scope parameter, or log in first if he hasn’t already done so, and then give consent. Further, with the user's consent, in automatic mode it will be transferred to the page specified in the redirect parameter.

Step 3

Returning back, the GET method will pass the code parameter, which contains the temporary code. With it, it is possible to request data for which the user has agreed. The parameter lifetime is 15 minutes. During this period, you need to get the access key to the access_token API from the requested site. It will look like this:

GET: REDIRECT_URI?code=a2a56603b8f57a6fa4dff77380df05206c883f011c40b72630bb5ed6f6479e52a8e
:
GET: REDIRECT_URI?error=invalid_request&error_description=Invalid+display+parameter


Step 4

At the final step, we get access by sending a request to z-payment.ru/api/get_access_token.php , the request as well as in step 1, can be transmitted via GET or POST method and must contain the following parameters:
client_id - a required parameter, a four-digit, unique identifier of the store in the z-payment system, issued when the store is registered in the Z-Payment merchant (see above)

code - a required parameter, a temporary code received after passing authorization in step 3 (see above)

format_answer is optional, response format, json is used by default. May take values: json, get.
client_secret is a required parameter and is an electronic signature. It is generated as a hash md5 from the merged string of request parameters and password of the Merchant Key store.
Data involved in the signature: client_id + code + MerchantKey - from this and take MD5

The result of the request must be a response consisting of parameters:
access_token, expires_in key lifetime (in seconds), user_id ZP number of the user_verification wallet - information about the user's certification (takes the value yes in case the user has a certificate), as well as a set of requested fields from the first request.

This completes the theoretical description of the authorization process, now
based on the above, you can make a software implementation of the protocol, I will do it on php 5.3 and it is assumed that the implemented class should be used in some MVC architecture.
So, the task is to make a simple class for automating authorization through Z-Payment. I want to immediately make a reservation on the code:
  1. define constants need to be placed in the configuration file, I use them in the example for clarity,
  2. I do not give an example of a class that implements the IUserStorage interface, data can be stored wherever it wants - a session (SessionUserStorage), a database (DbUserStorage) or a file (FileUserStorage), and therefore it is enough to know only the interface. The code is documented, so I consider additional commenting tediousness.

PHP code itself
 /** @desc ID      */ define("SHOP_ID", "0001"); /** @desc MERCHANT KEY      */ define("MERCHANT_KEY", "password"); namespace Example; /** @desc           */ interface IUserStorage { /** @desc     */ public function load(); /** @desc       */ public function save(array $data); /** @desc     */ public function erase(); } /** @desc     */ class UserManager { const TOKEN_URL = "https://z-payment.ru/api/get_access_token.php"; /** * @var \Example\IUserStorage * @desc  */ protected $storage; /** * @var $userInfo array * @desc     */ protected $userInfo; /** * @var \Example\Controller\Base * @desc     mvc ,      */ protected $controller; /** * @param IUserStorage $storage * @desc   $storage    \Example\IUserStorage */ public function __construct(\Example\IUserStorage $storage) { $this->storage = $storage; $this->userInfo = $this->storage->load(); } /** @desc   ,     */ public function getUserInfo($field = null) { if (null === $field) return $this->userInfo; if (isset($this->userInfo[$field])) return $this->userInfo[$field]; return null; } /** * @return bool * @desc     */ public function isLogin() { return ($this->userInfo != null); } /** * @desc  ZP  * @return string | null */ public function getAccount() { if (!$this->isLogin()) return null; return $this->userInfo['user_id']; } /** * @return bool * @desc       */ public function isCertified() { return ($this->getUserInfo('user_verification') == 'yes'); } /** * @return bool * @desc    */ public function Login() { /** @desc    code,  mvc   ,      $code = $_REQUEST['code']; */ $code = $this->controller->getRequest()->get("code"); /** * @desc  ,    md5     * 1+2+Merchant Key,  Merchant Key    */ $client_secret = md5(SHOP_ID . $code . MERCHANT_KEY); /** @desc     */ $params = array( /** id  */ 'client_id=' . urlencode(SHOP_ID), /**      */ 'code=' . urlencode($code), /**    */ 'format_answer=' . 'json', /**   */ 'client_secret=' . urlencode($client_secret) ); $curl = curl_init(self::TOKEN_URL); curl_setopt($curl, CURLOPT_HEADER, 1); curl_setopt($curl, CURLOPT_POST, 1); curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); curl_setopt($curl, CURLOPT_POSTFIELDS, implode("&", $params)); /** @desc    */ $result = curl_exec($curl); curl_close($curl); /** @desc    */ $result = json_decode($result); /** @desc     */ if ($result->error != null) return false; /** @desc    */ $this->storage->save((array)$result); return true; } /** * @desc   * @return void */ public function LogOut() { /** @desc   */ $this->storage->erase(); } /** * @param \Example\Controller\Base $controller * @return void * @desc   . */ public function setController(\Example\Controller\Base $controller) { $this->controller = $controller; /** * @var isLogin bool * @desc     */ $controller->getView()->isLogin = $this->isLogin(); /** @var $client_id int */ $client_id = SHOP_ID; /** * @var $redirect_uri string * @desc URL  */ $redirect_uri = "http://example_site_domain.org/login"; $display = "page"; /** * @var $scope strung * @desc   */ $scope = "f_name,s_name,m_name,sex,birth_day,group,e_mail,phone,country,city,balance"; if ($this->isLogin()) { /** @desc   ,      */ $controller->getView()->userName = $this->userInfo['f_name'] . " " . $this->userInfo['s_name']; } else { /** @desc    ,       */ $controller->getView()->linkZpAuth = sprintf("https://z-payment.ru/enter.php?client_id=%s&redirect_uri=%s&display=%s&scope=%s", $client_id, $redirect_uri, $display, $scope); } } } 


As you can see, the authorization process is almost identical to other Internet services offering this feature, especially if you look at the VKontakte API. :)

Thank you for your patience in the process of reading my humble work and I want to answer the question that you started to torment after reading the first paragraph - “Why should I screw up authorization through ZP, if they have significantly less users than VK, Gmail, Facebook, etc.?” , I answer: In contrast to the numerous implementations of the OAuth protocol on other sites, authorization through the Z-Payment API implies obtaining verified information about the user, and this is very important for all projects related to e-commerce.

Read more about the Z-Payment API in the InterfaceHTTPS.zip doc file.

Source: https://habr.com/ru/post/149243/


All Articles