VKでの人々の承認

どうした


こんにちは親愛なる読者。 Vkontakte APIを少なくとも1回使用したことがあり、すべてをpythonで記述したことがある場合、おそらくアプリケーションの承認により、スクワットを行うことを余儀なくされました。くそ


何らかの理由で、これは、最初は最も目立たない段階では膨大な時間と労力がかかるようです。 私の仕事:Habrの読者が足の怪我を避けるのを助ける


次に、特定のユーザーのアプリケーションを1行で認証してaccess_tokenを取得できる小さなライブラリを検討することを提案します。 記事の最後に、このライブラリのgithubリポジトリへのリンクがあり、 READMEファイルにクイックスタートがあります。


挑戦する


私たちは、美しく、普遍的かつ可能な限り信頼性の高い認証を可能にし、 非常に使いやすい小さなモジュールを求めています。
このソリューションは、 この記事で提案されたオプションの改善と一般化であると言う価値があります。


したがって、 python3.5のライブラリであるgetpassと隠しパスワードエントリのgetpass リクエストを使用します。


私たちのタスク:正しいアドレスに数回連絡し、毎回<form>解析し、応答を送信して、最終的に目的のaccess_token取得します。


実装


クラスを作成することから始めましょう。 初期化中に、アプリケーションがアクセスする「許可」のリスト、このアプリケーションのID、およびVK APIのバージョンが必要になります。 さらに、いくつかのオプションパラメータを追加します。各パラメータの意味は後で明らかになります。


__Init__メソッド
 class VKAuth(object): def __init__(self, permissions, app_id, api_v, email=None, pswd=None, two_factor_auth=False, security_code=None, auto_access=True): """ Args: permissions: list of Strings with permissions to get from API app_id: (String) vk app id that one can get from vk.com api_v: (String) vk API version """ self.session = requests.Session() self.form_parser = FormParser() self.user_id = None self.access_token = None self.response = None self.permissions = permissions self.api_v = api_v self.app_id = app_id self.two_factor_auth= two_factor_auth self.security_code = security_code self.email = email self.pswd = pswd self.auto_access = auto_access if security_code != None and two_factor_auth == False: raise RuntimeError('Security code provided for non-two-factor authorization') 

既に述べた記事で述べたように、クッキーとリダイレクトを巧みに変える必要があります。 Sessionクラスのオブジェクトを含むrequestsライブラリは、これをすべて行います。 self.sessionフィールドでそのようになります。 htmlドキュメントを解析するには、 html.parserモジュールの標準HTMLParserクラスを使用します。 クラス( FormParser )もパーサー用に記述されていますが、前述の記事からのクラスをほぼ完全に繰り返すため、あまり意味がありません。 唯一の重要な違いは、ここで使用されているものは、突然気が変わった場合に最後のステップでアプリケーションの承認を優雅に拒否できることです。


user_idおよびaccess_tokenは、認証が成功した後に入力され、 responseには最後のhtml要求の結果が格納されます。


ライブラリユーザーに、3つの手順を実行する1つのメソッドauthorizeを提供します。


  1. 申請承認申請
  2. ユーザー認証
    2.1二要素認証の場合のキーコードの紹介
  3. 許可確認

各ステップを見ていきましょう。


ステップ1.申請の承認を求める


リクエストURLを慎重に作成し(パラメーターについてはこちらで確認できます )、リクエストを送信し、受信したhtmlを解析します。


手順1の認証方法
 def authorize(self): api_auth_url = 'https://oauth.vk.com/authorize' app_id = self.app_id permissions = self.permissions redirect_uri = 'https://oauth.vk.com/blank.html' display = 'wap' api_version = self.api_v auth_url_template = '{0}?client_id={1}&scope={2}&redirect_uri={3}&display={4}&v={5}&response_type=token' auth_url = auth_url_template.format(api_auth_url, app_id, ','.join(permissions), redirect_uri, display, api_version) self.response = self.session.get(auth_url) # look for <form> element in response html and parse it if not self._parse_form(): raise RuntimeError('No <form> element found. Please, check url address') 

ステップ2.ユーザー認証


メソッド_log_in()および_two_fact_auth() 、VKのユーザーが許可されていない(および間違いなく許可されていない)場合、VKのユーザーの許可を成功させるために_two_fact_auth()れます。 両方のメソッドは、以前に定義されたemailpswdtwo_factor_authおよびsecurity_codeフィールドを使用します。 VKAuthクラスのオブジェクトを初期化するときに、フィールドのいずれかが引数として指定されなかった場合、コンソールに入力するように求められ、失敗した場合は再入力するように求められます。 二要素認証はオプションであり、デフォルトでは無効になっています。モジュールはエラーでユーザーにその存在を通知します。


手順2の認証方法(手順1の続き)
 #look for <form> element in response html and parse it if not self._parse_form(): raise RuntimeError('No <form> element found. Please, check url address') else: # try to log in with email and password (stored or expected to be entered) while not self._log_in(): pass; # handling two-factor authentication # expecting a security code to enter here if self.two_factor_auth: self._two_fact_auth() 

ステップ2の_Log_inメソッド
 def _log_in(self): if self.email == None: self.email = '' while self.email.strip() == '': self.email = input('Enter an email to log in: ') if self.pswd == None: self.pswd = '' while self.pswd.strip() == '': self.pswd = getpass.getpass('Enter the password: ') self._submit_form({'email': self.email, 'pass': self.pswd}) if not self._parse_form(): raise RuntimeError('No <form> element found. Please, check url address') # if wrong email or password if 'pass' in self.form_parser.params: print('Wrong email or password') self.email = None self.pswd = None return False elif 'code' in self.form_parser.params and not self.two_factor_auth: raise RuntimeError('Two-factor authentication expected from VK.\nChange `two_factor_auth` to `True` and provide a security code.') else: return True 

ステップ2の_Two_fact_authメソッド
 def _two_fact_auth(self): prefix = 'https://m.vk.com' if prefix not in self.form_parser.url: self.form_parser.url = prefix + self.form_parser.url if self.security_code == None: self.security_code = input('Enter security code for two-factor authentication: ') self._submit_form({'code': self.security_code}) if not self._parse_form(): raise RuntimeError('No <form> element found. Please, check url address') 

ステップ3. permissionsを確認し、 access_tokenを取得access_token


最も難しい部分は後ろにあります。 今では小さなものです。 フォームパーサーの改良を使用して、到着したばかりのhtmlドキュメントで「Allow」という碑文のボタンを見つけ、そこから承認確認URLを引き出します。 近くには拒否のボタンがあります-URLを保存します。 auto_accessフィールドはデフォルトでauto_accessているため、この確認は私たちの生活をこれ以上難しくするものではありません。


最後に、承認の確認後に送信されたURLから受信したaccess_tokenuser_id保存しuser_id


これで、VK APIを使用して楽しんでいただけます。


http:// REDIRECT_URI# access_token = 533bacf01e11f55b536a565b57531ad114461ae8736d6506a3&expires_in = 86400&user_id = 8492

手順3の認証方法
  # allow vk to use this app and access self.permissions self._allow_access() # now get access_token and user_id self._get_params() 

ステップ3の_Allow_accessメソッド
 def _allow_access(self): parser = self.form_parser if 'submit_allow_access' in parser.params and 'grant_access' in parser.url: if not self.auto_access: answer = '' msg = 'Application needs access to the following details in your profile:\n' + \ str(self.permissions) + '\n' + \ 'Allow it to use them? (yes or no)' attempts = 5 while answer not in ['yes', 'no'] and attempts > 0: answer = input(msg).lower().strip() attempts-=1 if answer == 'no' or attempts == 0: self.form_parser.url = self.form_parser.denial_url print('Access denied') self._submit_form({}) 

ステップ3の_Get_paramsメソッド
  def _get_params(self): try: params = self.response.url.split('#')[1].split('&') self.access_token = params[0].split('=')[1] self.user_id = params[2].split('=')[1] except IndexError(e): print(e) print('Coudln\'t fetch token') 

githubvkauth


こことgithubにコメントとレビューを残してください。 戦場で頑張って、足の世話をしてください。



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


All Articles