使用Swift 3的OAuth2 for MapMyRun [英] OAuth2 for MapMyRun using Swift 3

查看:110
本文介绍了使用Swift 3的OAuth2 for MapMyRun的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试让用户对我的应用进行身份验证以使用其存储在MapMyRun上的数据( https ://developer.underarmour.com/apps/myapps ).

I'm trying to get user to authenticate my app to work with his data stored on MapMyRun(https://developer.underarmour.com/apps/myapps).

这是我的代码:

let oauth2 = OAuth2CodeGrant(settings: [
    "client_id": "asdasdasd",
    "client_secret": "asdasdasd123",
    "authorize_uri": "https://www.mapmyfitness.com/v7.1/oauth2/uacf/authorize/?client_id=asdasdasd&response_type=code&redirect_uri=http://localhost.mapmyapi.com:12345/callback",
    "token_uri": "https://api.mapmyfitness.com/v7.1/oauth2/access_token/",
    "redirect_uris": ["http://localhost.mapmyapi.com:12345/callback"],
    "api-key":"asdasdasd",
    "grant_type": "authorization_code",
    "keychain": false,         // if you DON'T want keychain integration
    ] as OAuth2JSON)

override func viewDidLoad() {
    super.viewDidLoad()


        startAuthorization()


    // Do any additional setup after loading the view.
}


func startAuthorization() {
    oauth2.logger = OAuth2DebugLogger(.trace)

    oauth2.authorize() { authParameters, error in
        if let params = authParameters {
            print("Authorized! Access token is in `oauth2.accessToken`")
            print("Authorized! Additional parameters: \(params)")
        }
        else {
            print("Authorization was cancelled or went wrong: \(String(describing: error))")   // error will not be nil
        }
    }
}

我的输出:

[Debug] OAuth2: Starting authorization
[Debug] OAuth2: No access token, checking if a refresh token is available
[Debug] OAuth2: I don't have a refresh token, not trying to refresh
[Debug] OAuth2: Opening authorize URL in system browser: https://www.mapmyfitness.com/v7.1/oauth2/uacf/authorize/?redirect_uri=http%3A%2F%2Flocalhost.mapmyapi.com%3A12345%2Fcallback&client_id=asdasdasdasd&response_type=code&state=123123123

到目前为止,我得到的是

So far what I'm getting is a correct redirection on

http://localhost.mapmyapi.com:12345/callback + /callback state=&code=xxxxxxxxxxxxxxxxxxxxxxxx  

,但OAuth2无法处理.

but OAuth2 doesnt handle this.

如何使其通过MapMyRun进行身份验证? 我的想法是为例如实现深层链接. register://,这将是所有回调数据.而这将由下一个发布请求处理,该请求将使我们获得访问令牌.但这在我看来听起来有些复杂.

How to make it authenticate with MapMyRun? My idea is to implement a deeplink for eg. register:// and here would be all callback data. And this would be handled by next post request that will get us an access token.. But this sounds to me a bit to complicated.

还有其他解决方法吗?

Is there any other way to fix it?

我正在尝试重写可以完美运行的python代码,但现在我需要将其放在我的iOS应用程序中:D

I'm trying to rewrite my python code which works perfectly but now I need to put this on my iOS app :D

https://developer.underarmour.com/docs/v71_OAuth_2_Demo

import logging
import os
import sys
import urlparse
import webbrowser
from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
import requests

#logging.basicConfig(level=logging.DEBUG)

# Store your client ID and secret in your OS's environment using these keys, or
# redefine these values here.
CLIENT_ID = os.environ.setdefault("MMF_CLIENT_ID", "asdasdasdasd")
CLIENT_SECRET = os.environ.setdefault("MMF_CLIENT_SECRET", "asdasdasd123123")

print CLIENT_ID
if CLIENT_ID is None or CLIENT_SECRET is None:
    print 'Please ensure $MMF_CLIENT_ID and $MMF_CLIENT_SECRET environment ' \
          'variables are set.'
    sys.exit(1)

# As a convenience, localhost.mapmyapi.com redirects to localhost.
redirect_uri = 'http://localhost.mapmyapi.com:12345/callback'
authorize_url = 'https://www.mapmyfitness.com/v7.1/oauth2/uacf/authorize/?' \
                'client_id={0}&response_type=code&redirect_uri={1}'.format(CLIENT_ID, redirect_uri)


# Set up a basic handler for the redirect issued by the MapMyFitness
# authorize page. For any GET request, it simply returns a 200.
# When run interactively, the request's URL will be printed out.
class AuthorizationHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        self.send_response(200, 'OK')
        self.send_header('Content-Type', 'text/html')
        self.end_headers()
        self.server.path = self.path


parsed_redirect_uri = urlparse.urlparse(redirect_uri)
server_address = parsed_redirect_uri.hostname, parsed_redirect_uri.port

print 'server_address:', server_address

# NOTE: Don't go to the web browser just yet...
webbrowser.open(authorize_url)

# Start our web server. handle_request() will block until a request comes in.
httpd = HTTPServer(server_address, AuthorizationHandler)
print 'Now waiting for the user to authorize the application...'
httpd.handle_request()

# At this point a request has been handled. Let's parse its URL.
httpd.server_close()
callback_url = urlparse.urlparse(httpd.path)
authorize_code = urlparse.parse_qs(callback_url.query)['code'][0]

print 'Got an authorize code:', authorize_code

access_token_url = 'https://api.mapmyfitness.com/v7.1/oauth2/access_token/'
access_token_data = {'grant_type': 'authorization_code',
                     'client_id': CLIENT_ID,
                     'client_secret': CLIENT_SECRET,
                     'code': authorize_code}

response = requests.post(url=access_token_url,
                         data=access_token_data,
                         headers={'Api-Key': CLIENT_ID})

print 'Request details:'
print 'Content-Type:', response.request.headers['Content-Type']
print 'Request body:', response.request.body

# retrieve the access_token from the response
try:
    access_token = response.json()
    print 'Got an access token:', access_token
except:
    print 'Did not get JSON. Here is the response and content:'
    print response
    print response.content

# Use the access token to request a resource on behalf of the user
activity_type_url = 'https://api.ua.com/v7.1/activity_type/'
response = requests.get(url=activity_type_url, verify=False,
                        headers={'api-key': CLIENT_ID, 'authorization': 'Bearer %s' % access_token['access_token']})

# Refresh a client's credentials to prevent expiration
refresh_token_url = 'https://api.ua.com/v7.1/oauth2/uacf/access_token/'
refresh_token_data = {'grant_type': 'refresh_token',
                      'client_id': CLIENT_ID,
                      'client_secret': CLIENT_SECRET,
                      'refresh_token': access_token['refresh_token']}

response = requests.post(url=refresh_token_url, data=refresh_token_data,
                         headers={'api-key': CLIENT_ID, 'authorization': 'Bearer %s' % access_token['access_token']})

print 'Request details:'
print 'Content-Type:', response.request.headers['Content-Type']
print 'Request body:', response.request.body

try:
    access_token = response.json()
    print 'Got an access token:', access_token
except:
    print 'Did not get JSON. Here is the response and content:'
    print response
    print response.content

# Attempt another request on the user's behalf using the token
refresh_token = response.json()
response = requests.get(url=activity_type_url, verify=False,
                        headers={'api-key': CLIENT_ID, 'authorization': 'Bearer %s' % access_token['access_token']})

谢谢!

抄送:@Makaille

CC: @Makaille

推荐答案

我解决了我的问题.

  1. 我将深度链接设置为重定向到我的应用程序:register://callback

  1. I set a deeplink redirecting to my app: register://callback

然后在我的应用程序的mapmyrun设置中,我设置了一个指向我的Deeplink的回调链接.我用ruby编写,它位于我的后端服务器上:

Then in mapmyrun settings for my app I set a callback link pointing to my deeplink. I wrote it in ruby and this sits on my backend server:

#!/usr/bin/env ruby
require 'rubygems'
require 'sinatra'

get '/mapmyruncallback' do
    redirect 'register://callback'
end

  • 然后在AppDelegate.swift中,我输入"oauth2.handleRedirectURL(url)"

  • Then in AppDelegate.swift I put "oauth2.handleRedirectURL(url)"

    func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
    
        print("url path :\(url)")
    
    
        oauth2.handleRedirectURL(url)
        return true
    }
    

  • 瞧! :)

  • voilà! :)

    这篇关于使用Swift 3的OAuth2 for MapMyRun的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆