2017-04-20 7 views
0

사용자가 MapMyRun (https://developer.underarmour.com/apps/myapps)에 저장된 그의 데이터로 작업하도록 내 앱을 인증하도록하려고합니다. 무엇을 내가 갖는 것은Swift 3를 사용하는 MapMyRun 용 OAuth2

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

하지만 OAuth2를 나던 핸들에 올바른 리디렉션입니다 지금까지

[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 

:

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 
     } 
    } 
} 

그리고 내 출력 : 여기에

내 코드입니다 이.

MapMyRun으로 인증하는 방법은 무엇입니까? 제 아이디어는 예를 들어 딥 링크를 구현하는 것입니다. register : // 여기에 모든 콜백 데이터가 있습니다. 그리고 이것은 우리에게 액세스 토큰을 얻을 수있는 다음 게시물 요청에 의해 처리 될 것입니다. 그러나 이것은 약간 복잡하게 들립니다.

다른 해결책이 있습니까?

나는 완벽하게 작동 내 파이썬 코드를 다시 작성하기 위해 노력하고있어하지만 지금은 내 iOS 앱에이 둘 필요 : 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']}) 

감사합니다!

CC : @Makaille

답변

0

나는 내 문제를 해결했다.

  1. 나는 내 애플 리케이션에 딥 링크 리디렉션을 설정 등록 : // 콜백

  2. 을 다음 mapmyrun 설정에서 내 앱 내 딥 링크를 가리키는 콜백 링크를 설정합니다. 나는 루비에 쓴이 내 백엔드 서버에 앉아 :

    #!/usr/bin/env ruby 
    require 'rubygems' 
    require 'sinatra' 
    
    get '/mapmyruncallback' do 
        redirect 'register://callback' 
    end 
    
  3. 그런 다음 AppDelegate.swift에서 나는 "oauth2.handleRedirectURL (URL)"

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