<?xml version="1.0" encoding="utf-8" ?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:tt="http://teletype.in/" xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/"><title>Kirill Letnikov</title><author><name>Kirill Letnikov</name></author><id>https://teletype.in/atom/letnikov.kirill</id><link rel="self" type="application/atom+xml" href="https://teletype.in/atom/letnikov.kirill?offset=0"></link><link rel="alternate" type="text/html" href="https://teletype.in/@letnikov.kirill?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=letnikov.kirill"></link><link rel="next" type="application/rss+xml" href="https://teletype.in/atom/letnikov.kirill?offset=10"></link><link rel="search" type="application/opensearchdescription+xml" title="Teletype" href="https://teletype.in/opensearch.xml"></link><updated>2026-09-23T01:39:14.109Z</updated><entry><id>letnikov.kirill:QS1pHwO-Z</id><link rel="alternate" type="text/html" href="https://teletype.in/@letnikov.kirill/QS1pHwO-Z?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=letnikov.kirill"></link><title>x5SSOSDK iOS framework v1.2</title><published>2021-04-05T19:50:44.232Z</published><updated>2021-07-27T12:45:18.118Z</updated><summary type="html">Вся работа с авторизацией происходит через класс AuthManager. Для его инициализации необходимо передать исходный ViewControler и объект конфигурации, который представлен классом Configuration. </summary><content type="html">
  &lt;h2&gt;Использование:&lt;/h2&gt;
  &lt;p&gt;Вся работа с авторизацией происходит через класс AuthManager. Для его инициализации необходимо передать исходный ViewControler и объект конфигурации, который представлен классом Configuration. &lt;/p&gt;
  &lt;p&gt;Пример:&lt;/p&gt;
  &lt;pre&gt;var manager: AuthManager?&lt;/pre&gt;
  &lt;pre&gt;override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        let config = Configuration(
            webAuthUrl: webAuthUrl,
            tokenUrl: tokenUrl,
            callBackUrl: callBackUrl,
            exchangeLegacyTokenUrl: exchangeLegacyTokenUrl,
            manageAgreementsUrl: manageAgreementsUrl,
            clientID: clientID,
            flow: AuthorizationFlow)
        manager = AuthManager(viewControler: self, config: config)
}&lt;/pre&gt;
  &lt;p&gt;В примере (SSOX5ExampleFirst) используются следующие параметры конфигурации:&lt;/p&gt;
  &lt;pre&gt;let webAuthUrl = URL(string: &amp;quot;http://85.192.35.25:33000/scan-go?redirect_url=ru.ramax.a5ka://oauth2redirect&amp;quot;)!
let tokenUrl = URL(string: &amp;quot;http://85.192.35.25:33000/auth/realms/ssox5id/protocol/openid-connect/token&amp;quot;)!
let callBackUrl = URL(string: &amp;quot;ru.ramax.a5ka://oauth2redirect&amp;quot;)!
let exchangeLegacyTokenUrl = URL(string: &amp;quot;http://85.192.35.25:33000/migration/save/token&amp;quot;)!
let manageAgreementsUrl = URL(string: &amp;quot;http://85.192.35.25:33000/migration/save/agreement&amp;quot;)!
let clientID = &amp;quot;scan-go&amp;quot;
let flow = .token&lt;/pre&gt;
  &lt;p&gt;&lt;strong&gt;&lt;em&gt;*AuthorizationFlow:&lt;/em&gt;&lt;/strong&gt; flow может принимать значения AuthorizationFlow.token либо AuthorizationFlow.code. Соответственно для методов &amp;#x27;auth&amp;#x27; и &amp;#x27;exchangeLegacyToken&amp;#x27;:&lt;/p&gt;
  &lt;ul&gt;
    &lt;li&gt;Для значения .token будет выполнен стандартный процесс авторизации с получением authorizationCode и последующим обменом его на token. В случае успеха в result будет возвращен token.&lt;/li&gt;
    &lt;li&gt;Для значения .code в процессе авторизации будет получен только authorizationCode. Обмен на token не будет выполнен. В случае успеха в result будет возвращен authorizationCode.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p&gt;&lt;strong&gt;Auth:&lt;/strong&gt;&lt;/p&gt;
  &lt;p&gt;Для авторизации используется метод:&lt;/p&gt;
  &lt;pre&gt;public func auth(completion: @escaping (Result&amp;lt;String, Error&amp;gt;) -&amp;gt; Void)&lt;/pre&gt;
  &lt;p&gt;Пример использования:&lt;/p&gt;
  &lt;pre&gt;func startAuth() {
        manager?.auth() { (result) in
            switch result {
            case .success(let token):
                print(&amp;quot;Success. Token: &amp;quot; + token)
            case .failure(let error):
                print(&amp;quot;Failure. Error: &amp;quot; + b.localizedDescription)
            }
        }   
}&lt;/pre&gt;
  &lt;p&gt;&lt;/p&gt;
  &lt;p&gt;&lt;strong&gt;IsAuthorized:&lt;/strong&gt;&lt;/p&gt;
  &lt;p&gt;Для проверки авторизован ли пользователь используется свойство:&lt;/p&gt;
  &lt;pre&gt;public var isAuthorized: Bool { get }&lt;/pre&gt;
  &lt;p&gt;&lt;strong&gt;&lt;em&gt;*AuthorizationFlow:&lt;/em&gt;&lt;/strong&gt; Данное свойство актуально только для &amp;#x27;flow = AuthorizationFlow.token&amp;#x27;. Для &amp;#x27;flow = AuthorizationFlow.token&amp;#x27; isAuthorized всегда будет равно false.&lt;/p&gt;
  &lt;p&gt;Пример использования:&lt;/p&gt;
  &lt;pre&gt;let isHiddenLogin = manager?.isAuthorized ?? false&lt;/pre&gt;
  &lt;p&gt;&lt;/p&gt;
  &lt;p&gt;&lt;strong&gt;RefreshToken:&lt;/strong&gt;&lt;/p&gt;
  &lt;p&gt;Для получения RefreshToken используется метод:&lt;/p&gt;
  &lt;pre&gt;public func refreshToken(completion: @escaping (Result&amp;lt;String, Error&amp;gt;) -&amp;gt; Void)&lt;/pre&gt;
  &lt;p&gt;Пример использования:&lt;/p&gt;
  &lt;pre&gt;manager?.refreshToken { (result) in
            switch result {
            case .success(let token):
                print(&amp;quot;token: &amp;quot; + token)
            case .failure(let error):
                print(&amp;quot;error: &amp;quot; + error.localizedDescription )
            }
}&lt;/pre&gt;
  &lt;p&gt;&lt;/p&gt;
  &lt;p&gt;&lt;strong&gt;AccessToken:&lt;/strong&gt;&lt;/p&gt;
  &lt;p&gt;Для получения AccessToken используется свойство:&lt;/p&gt;
  &lt;pre&gt;public var accessToken: String? { get }&lt;/pre&gt;
  &lt;p&gt;Пример использования:&lt;/p&gt;
  &lt;pre&gt;print(&amp;quot;AccessToken: &amp;quot;, manager?.accessToken)&lt;/pre&gt;
  &lt;p&gt;&lt;/p&gt;
  &lt;p&gt;&lt;strong&gt;СheckToken:&lt;/strong&gt;&lt;/p&gt;
  &lt;p&gt;Для расшифровки JWT токена используется метод:&lt;/p&gt;
  &lt;pre&gt;public func checkToken(_ token: String) -&amp;gt; JWTCheckResult&lt;/pre&gt;
  &lt;p&gt;JWTCheckResult содержит следующие параметры:&lt;/p&gt;
  &lt;pre&gt;public let isX5ssoToken: Bool
public let permissionMarketing: Bool
public let isUnifiedAgreement: Bool&lt;/pre&gt;
  &lt;p&gt;Пример использования:&lt;/p&gt;
  &lt;pre&gt;let checkResult = manager?.checkToken(token)&lt;/pre&gt;
  &lt;p&gt;&lt;/p&gt;
  &lt;p&gt;&lt;strong&gt;ExchangeLegacyToken:&lt;/strong&gt;&lt;/p&gt;
  &lt;p&gt;Для обмена legacy token&amp;#x27;а на код используется метод:&lt;/p&gt;
  &lt;pre&gt;public func exchangeLegacyToken(_ token: String, completion: @escaping (Result&amp;lt;String, Error&amp;gt;) -&amp;gt; Void )&lt;/pre&gt;
  &lt;p&gt;Пример использования:&lt;/p&gt;
  &lt;pre&gt;manager?.exchangeLegacyToken(token, completion: { [weak self] (result) in
            switch result {
            case .success(let accessToken):
                self?.showAlert(title: &amp;quot;Success&amp;quot;,
                                message: accessToken)
            case .failure(let error):
                self?.showAlert(title: &amp;quot;Failure&amp;quot;,
                                message: error.localizedDescription)
            }
})&lt;/pre&gt;
  &lt;p&gt;&lt;/p&gt;
  &lt;p&gt;&lt;strong&gt;ManageAgreements:&lt;/strong&gt;&lt;/p&gt;
  &lt;p&gt;Для передачи соглашений используется метод:&lt;/p&gt;
  &lt;pre&gt;public func manageAgreements(_ agreements: Agreements, 
                              accessToken: String? = nil,
                               completion: @escaping (Result&amp;lt;String, Error&amp;gt;) -&amp;gt; Void )&lt;/pre&gt;
  &lt;p&gt;&lt;strong&gt;&lt;em&gt;*AuthorizationFlow:&lt;/em&gt;&lt;/strong&gt; параметр accessToken необходим только для &amp;#x27;flow = AuthorizationFlow.code&amp;#x27;.&lt;/p&gt;
  &lt;p&gt;Пример использования:&lt;/p&gt;
  &lt;pre&gt;let adsAgreementChannels = AdsAgreementChannels(sms: true,
                                               mail: true,
                                               push: true,
                                              phone: true,
                                              offer: true)
let agreements = Agreements(     userIP: &amp;quot;192.168.0.1&amp;quot;,
                             userDevice: &amp;quot;iPhone&amp;quot;,
                      commercialNetwork: &amp;quot;exapmle_name&amp;quot;,
            userAgreementLoyaltyProgram: true,
                        isBaseAgreement: true,
                    isExtendedAgreement: true,
                     isUnifiedAgreement: true,
                 isAdsAgreementChannels: adsAgreementChannels)
            manager?.manageAgreements(agreements, completion: { [weak self] (result) in
            switch result {
            case .success(let dataString):
                self?.showAlert(title: &amp;quot;Success&amp;quot;,
                                message: dataString)
            case .failure(let error):
                self?.showAlert(title: &amp;quot;Failure&amp;quot;,
                                message: error.localizedDescription)
            }
})&lt;/pre&gt;
  &lt;p&gt;&lt;/p&gt;
  &lt;h2&gt;Обработка ошибок:&lt;/h2&gt;
  &lt;ul&gt;
    &lt;li&gt;Ошибки представлены объектами класса NSError из Foundation и передаются в failure result completion блока.&lt;/li&gt;
    &lt;li&gt;При работе с сервисами в первую очередь x5SSOSDK проверяет наличие подключения и в случае его отсутствия возвращает ошибку с кодом 617. &lt;/li&gt;
    &lt;li&gt;Если ошибка возникает на уровне AppAuth, то она будет передана в completion блок без дополнительной обработки.&lt;/li&gt;
    &lt;li&gt;Если ошибка возникает на уровне x5SSOSDK, то при наличии тела http ответа, оно будет добавлено в словарь NSError.userInfo с ключом &amp;quot;x5SSOSDK_HTTPResponseData&amp;quot;.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;h3&gt;Коды ошибок x5SSOSDK:&lt;/h3&gt;
  &lt;p&gt;617 - Отсутствует подключение к сети.&lt;/p&gt;
  &lt;p&gt;401 - Не валидный токен.&lt;/p&gt;
  &lt;p&gt;500 - Любая другая ошибка.&lt;/p&gt;

</content></entry></feed>