<?xml version="1.0" encoding="utf-8" ?><rss version="2.0" xmlns:tt="http://teletype.in/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:media="http://search.yahoo.com/mrss/"><channel><title>Kirill Letnikov</title><generator>teletype.in</generator><description><![CDATA[Kirill Letnikov]]></description><image><url>https://teletype.in/files/eb/4b/eb4b5153-8472-4ffc-b665-38d802e22bd6.png</url><title>Kirill Letnikov</title><link>https://teletype.in/@letnikov.kirill</link></image><link>https://teletype.in/@letnikov.kirill?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=letnikov.kirill</link><atom:link rel="self" type="application/rss+xml" href="https://teletype.in/rss/letnikov.kirill?offset=0"></atom:link><atom:link rel="next" type="application/rss+xml" href="https://teletype.in/rss/letnikov.kirill?offset=10"></atom:link><atom:link rel="search" type="application/opensearchdescription+xml" title="Teletype" href="https://teletype.in/opensearch.xml"></atom:link><pubDate>Wed, 23 Sep 2026 01:39:20 GMT</pubDate><lastBuildDate>Wed, 23 Sep 2026 01:39:20 GMT</lastBuildDate><item><guid isPermaLink="true">https://teletype.in/@letnikov.kirill/QS1pHwO-Z</guid><link>https://teletype.in/@letnikov.kirill/QS1pHwO-Z?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=letnikov.kirill</link><comments>https://teletype.in/@letnikov.kirill/QS1pHwO-Z?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=letnikov.kirill#comments</comments><dc:creator>letnikov.kirill</dc:creator><title>x5SSOSDK iOS framework v1.2</title><pubDate>Mon, 05 Apr 2021 19:50:44 GMT</pubDate><description><![CDATA[Вся работа с авторизацией происходит через класс AuthManager. Для его инициализации необходимо передать исходный ViewControler и объект конфигурации, который представлен классом Configuration. ]]></description><content:encoded><![CDATA[
  <h2>Использование:</h2>
  <p>Вся работа с авторизацией происходит через класс AuthManager. Для его инициализации необходимо передать исходный ViewControler и объект конфигурации, который представлен классом Configuration. </p>
  <p>Пример:</p>
  <pre>var manager: AuthManager?</pre>
  <pre>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)
}</pre>
  <p>В примере (SSOX5ExampleFirst) используются следующие параметры конфигурации:</p>
  <pre>let webAuthUrl = URL(string: &quot;http://85.192.35.25:33000/scan-go?redirect_url=ru.ramax.a5ka://oauth2redirect&quot;)!
let tokenUrl = URL(string: &quot;http://85.192.35.25:33000/auth/realms/ssox5id/protocol/openid-connect/token&quot;)!
let callBackUrl = URL(string: &quot;ru.ramax.a5ka://oauth2redirect&quot;)!
let exchangeLegacyTokenUrl = URL(string: &quot;http://85.192.35.25:33000/migration/save/token&quot;)!
let manageAgreementsUrl = URL(string: &quot;http://85.192.35.25:33000/migration/save/agreement&quot;)!
let clientID = &quot;scan-go&quot;
let flow = .token</pre>
  <p><strong><em>*AuthorizationFlow:</em></strong> flow может принимать значения AuthorizationFlow.token либо AuthorizationFlow.code. Соответственно для методов &#x27;auth&#x27; и &#x27;exchangeLegacyToken&#x27;:</p>
  <ul>
    <li>Для значения .token будет выполнен стандартный процесс авторизации с получением authorizationCode и последующим обменом его на token. В случае успеха в result будет возвращен token.</li>
    <li>Для значения .code в процессе авторизации будет получен только authorizationCode. Обмен на token не будет выполнен. В случае успеха в result будет возвращен authorizationCode.</li>
  </ul>
  <p><strong>Auth:</strong></p>
  <p>Для авторизации используется метод:</p>
  <pre>public func auth(completion: @escaping (Result&lt;String, Error&gt;) -&gt; Void)</pre>
  <p>Пример использования:</p>
  <pre>func startAuth() {
        manager?.auth() { (result) in
            switch result {
            case .success(let token):
                print(&quot;Success. Token: &quot; + token)
            case .failure(let error):
                print(&quot;Failure. Error: &quot; + b.localizedDescription)
            }
        }   
}</pre>
  <p></p>
  <p><strong>IsAuthorized:</strong></p>
  <p>Для проверки авторизован ли пользователь используется свойство:</p>
  <pre>public var isAuthorized: Bool { get }</pre>
  <p><strong><em>*AuthorizationFlow:</em></strong> Данное свойство актуально только для &#x27;flow = AuthorizationFlow.token&#x27;. Для &#x27;flow = AuthorizationFlow.token&#x27; isAuthorized всегда будет равно false.</p>
  <p>Пример использования:</p>
  <pre>let isHiddenLogin = manager?.isAuthorized ?? false</pre>
  <p></p>
  <p><strong>RefreshToken:</strong></p>
  <p>Для получения RefreshToken используется метод:</p>
  <pre>public func refreshToken(completion: @escaping (Result&lt;String, Error&gt;) -&gt; Void)</pre>
  <p>Пример использования:</p>
  <pre>manager?.refreshToken { (result) in
            switch result {
            case .success(let token):
                print(&quot;token: &quot; + token)
            case .failure(let error):
                print(&quot;error: &quot; + error.localizedDescription )
            }
}</pre>
  <p></p>
  <p><strong>AccessToken:</strong></p>
  <p>Для получения AccessToken используется свойство:</p>
  <pre>public var accessToken: String? { get }</pre>
  <p>Пример использования:</p>
  <pre>print(&quot;AccessToken: &quot;, manager?.accessToken)</pre>
  <p></p>
  <p><strong>СheckToken:</strong></p>
  <p>Для расшифровки JWT токена используется метод:</p>
  <pre>public func checkToken(_ token: String) -&gt; JWTCheckResult</pre>
  <p>JWTCheckResult содержит следующие параметры:</p>
  <pre>public let isX5ssoToken: Bool
public let permissionMarketing: Bool
public let isUnifiedAgreement: Bool</pre>
  <p>Пример использования:</p>
  <pre>let checkResult = manager?.checkToken(token)</pre>
  <p></p>
  <p><strong>ExchangeLegacyToken:</strong></p>
  <p>Для обмена legacy token&#x27;а на код используется метод:</p>
  <pre>public func exchangeLegacyToken(_ token: String, completion: @escaping (Result&lt;String, Error&gt;) -&gt; Void )</pre>
  <p>Пример использования:</p>
  <pre>manager?.exchangeLegacyToken(token, completion: { [weak self] (result) in
            switch result {
            case .success(let accessToken):
                self?.showAlert(title: &quot;Success&quot;,
                                message: accessToken)
            case .failure(let error):
                self?.showAlert(title: &quot;Failure&quot;,
                                message: error.localizedDescription)
            }
})</pre>
  <p></p>
  <p><strong>ManageAgreements:</strong></p>
  <p>Для передачи соглашений используется метод:</p>
  <pre>public func manageAgreements(_ agreements: Agreements, 
                              accessToken: String? = nil,
                               completion: @escaping (Result&lt;String, Error&gt;) -&gt; Void )</pre>
  <p><strong><em>*AuthorizationFlow:</em></strong> параметр accessToken необходим только для &#x27;flow = AuthorizationFlow.code&#x27;.</p>
  <p>Пример использования:</p>
  <pre>let adsAgreementChannels = AdsAgreementChannels(sms: true,
                                               mail: true,
                                               push: true,
                                              phone: true,
                                              offer: true)
let agreements = Agreements(     userIP: &quot;192.168.0.1&quot;,
                             userDevice: &quot;iPhone&quot;,
                      commercialNetwork: &quot;exapmle_name&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: &quot;Success&quot;,
                                message: dataString)
            case .failure(let error):
                self?.showAlert(title: &quot;Failure&quot;,
                                message: error.localizedDescription)
            }
})</pre>
  <p></p>
  <h2>Обработка ошибок:</h2>
  <ul>
    <li>Ошибки представлены объектами класса NSError из Foundation и передаются в failure result completion блока.</li>
    <li>При работе с сервисами в первую очередь x5SSOSDK проверяет наличие подключения и в случае его отсутствия возвращает ошибку с кодом 617. </li>
    <li>Если ошибка возникает на уровне AppAuth, то она будет передана в completion блок без дополнительной обработки.</li>
    <li>Если ошибка возникает на уровне x5SSOSDK, то при наличии тела http ответа, оно будет добавлено в словарь NSError.userInfo с ключом &quot;x5SSOSDK_HTTPResponseData&quot;.</li>
  </ul>
  <h3>Коды ошибок x5SSOSDK:</h3>
  <p>617 - Отсутствует подключение к сети.</p>
  <p>401 - Не валидный токен.</p>
  <p>500 - Любая другая ошибка.</p>

]]></content:encoded></item></channel></rss>