استفاده از OAuth 2.0 برای برنامه های کاربردی وب سرور
با مجموعهها، منظم بمانید
ذخیره و طبقهبندی محتوا براساس اولویتهای شما.
این سند توضیح میدهد که چگونه برنامههای وب سرور از کتابخانههای کلاینت API گوگل یا نقاط پایانی Google OAuth 2.0 برای پیادهسازی مجوز OAuth 2.0 جهت دسترسی به APIهای گوگل استفاده میکنند.
OAuth 2.0 به کاربران اجازه میدهد دادههای خاصی را با یک برنامه به اشتراک بگذارند، در حالی که نام کاربری، رمز عبور و سایر اطلاعات آنها خصوصی باقی میماند. به عنوان مثال، یک برنامه میتواند از OAuth 2.0 برای دریافت مجوز از کاربران برای ذخیره فایلها در Google Drives آنها استفاده کند.
این جریان OAuth 2.0 به طور خاص برای احراز هویت کاربر است. این جریان برای برنامههایی طراحی شده است که میتوانند اطلاعات محرمانه را ذخیره کرده و وضعیت را حفظ کنند. یک برنامه وب سرور که به درستی احراز هویت شده باشد، میتواند در حین تعامل کاربر با برنامه یا پس از ترک برنامه، به یک API دسترسی داشته باشد.
برنامههای وب سرور اغلب از حسابهای سرویس برای تأیید درخواستهای API نیز استفاده میکنند، به خصوص هنگام فراخوانی APIهای ابری برای دسترسی به دادههای مبتنی بر پروژه به جای دادههای خاص کاربر. برنامههای وب سرور میتوانند از حسابهای سرویس همراه با تأیید کاربر استفاده کنند.
کتابخانههای کلاینت
مثالهای مختص زبان در این صفحه از کتابخانههای کلاینت API گوگل برای پیادهسازی احراز هویت OAuth 2.0 استفاده میکنند. برای اجرای نمونههای کد، ابتدا باید کتابخانه کلاینت را برای زبان خود نصب کنید.
وقتی از یک کتابخانه کلاینت API گوگل برای مدیریت جریان OAuth 2.0 برنامه خود استفاده میکنید، کتابخانه کلاینت اقدامات زیادی را انجام میدهد که در غیر این صورت برنامه باید به تنهایی آنها را مدیریت کند. به عنوان مثال، تعیین میکند که چه زمانی برنامه میتواند از توکنهای دسترسی ذخیره شده استفاده کند یا آنها را بهروزرسانی کند و همچنین چه زمانی برنامه باید رضایت را دوباره کسب کند. کتابخانه کلاینت همچنین URLهای هدایت مجدد صحیح را تولید میکند و به پیادهسازی کنترلکنندههای هدایت مجدد که کدهای مجوز را برای توکنهای دسترسی مبادله میکنند، کمک میکند.
کتابخانههای کلاینت API گوگل برای برنامههای سمت سرور برای زبانهای زیر در دسترس هستند:
If prompted, select a project, or create a new one.
API Library تمام APIهای موجود را که بر اساس خانواده محصول و محبوبیت گروهبندی شدهاند، فهرست میکند. اگر API مورد نظر برای فعالسازی در لیست قابل مشاهده نیست، از جستجو برای یافتن آن استفاده کنید یا روی مشاهده همه در خانواده محصولی که به آن تعلق دارد کلیک کنید.
API مورد نظر خود را انتخاب کنید و سپس روی دکمهی فعالسازی کلیک کنید.
If prompted, enable billing.
If prompted, read and accept the API's Terms of Service.
ایجاد اعتبارنامههای مجوز
هر برنامهای که از OAuth 2.0 برای دسترسی به APIهای گوگل استفاده میکند، باید دارای اعتبارنامههای احراز هویت باشد که برنامه را به سرور OAuth 2.0 گوگل معرفی کند. مراحل زیر نحوه ایجاد اعتبارنامه برای پروژه شما را توضیح میدهد. سپس برنامههای شما میتوانند از این اعتبارنامهها برای دسترسی به APIهایی که برای آن پروژه فعال کردهاید، استفاده کنند.
فرم را پر کنید و روی ایجاد کلیک کنید. برنامههایی که از زبانها و چارچوبهایی مانند PHP، Java، Python، Ruby و .NET استفاده میکنند، باید URI های ریدایرکت مجاز را مشخص کنند. URI های ریدایرکت، نقاط پایانی هستند که سرور OAuth 2.0 میتواند به آنها پاسخ ارسال کند. این نقاط پایانی باید از قوانین اعتبارسنجی گوگل پیروی کنند.
برای آزمایش، میتوانید URIهایی را مشخص کنید که به دستگاه محلی اشاره دارند، مانند http://localhost:8080 . با توجه به این نکته، لطفاً توجه داشته باشید که تمام مثالهای این سند از http://localhost:8080 به عنوان URI تغییر مسیر استفاده میکنند.
پس از ایجاد اعتبارنامههای خود، فایل client_secret.json را از اینجا دانلود کنید. API Consoleفایل را به طور ایمن در مکانی ذخیره کنید که فقط برنامه شما بتواند به آن دسترسی داشته باشد.
شناسایی محدودههای دسترسی
محدودهها به برنامه شما این امکان را میدهند که فقط به منابعی که نیاز دارد درخواست دسترسی کند و در عین حال کاربران را قادر میسازد میزان دسترسی که به برنامه شما میدهند را کنترل کنند. بنابراین، ممکن است رابطه معکوسی بین تعداد محدودههای درخواستی و احتمال کسب رضایت کاربر وجود داشته باشد.
قبل از شروع پیادهسازی احراز هویت OAuth 2.0، توصیه میکنیم محدودههایی را که برنامه شما برای دسترسی به آنها نیاز به مجوز دارد، شناسایی کنید.
ما همچنین توصیه میکنیم که برنامه شما از طریق یک فرآیند مجوزدهی افزایشی ، درخواست دسترسی به حوزههای مجوز را ارائه دهد، که در آن برنامه شما درخواست دسترسی به دادههای کاربر را در متن مربوطه ارائه میدهد. این روش برتر به کاربران کمک میکند تا راحتتر درک کنند که چرا برنامه شما به دسترسی مورد نظر خود نیاز دارد.
سند OAuth 2.0 API Scopes شامل لیست کاملی از scopeهایی است که ممکن است برای دسترسی به APIهای گوگل از آنها استفاده کنید.
الزامات خاص زبان
برای اجرای هر یک از نمونههای کد موجود در این سند، به یک حساب گوگل، دسترسی به اینترنت و یک مرورگر وب نیاز دارید. اگر از یکی از کتابخانههای کلاینت API استفاده میکنید، الزامات خاص زبان را نیز در زیر مشاهده کنید.
پی اچ پی
برای اجرای نمونههای کد PHP در این سند، به موارد زیر نیاز دارید:
PHP 8.0 یا بالاتر با رابط خط فرمان (CLI) و افزونه JSON نصب شده.
برای اینکه بتوانید مستقیماً نقاط پایانی OAuth 2.0 را فراخوانی کنید، نیازی به نصب هیچ کتابخانهای ندارید.
دریافت توکنهای دسترسی OAuth 2.0
مراحل زیر نشان میدهد که چگونه برنامه شما با سرور OAuth 2.0 گوگل تعامل میکند تا رضایت کاربر را برای انجام یک درخواست API از طرف کاربر دریافت کند. برنامه شما باید قبل از اینکه بتواند یک درخواست API گوگل را که نیاز به مجوز کاربر دارد اجرا کند، این رضایت را داشته باشد.
لیست زیر به سرعت این مراحل را خلاصه میکند:
برنامه شما مجوزهای مورد نیاز خود را شناسایی میکند.
برنامه شما کاربر را به همراه لیست مجوزهای درخواستی به گوگل هدایت میکند.
کاربر تصمیم میگیرد که آیا مجوزهای لازم را به برنامه شما اعطا کند یا خیر.
برنامه شما متوجه میشود که کاربر چه تصمیمی گرفته است.
اگر کاربر مجوزهای درخواستی را اعطا کرده باشد، برنامه شما توکنهای مورد نیاز برای ارسال درخواستهای API از طرف کاربر را بازیابی میکند.
مرحله ۱: تنظیم پارامترهای مجوز
اولین قدم شما ایجاد درخواست مجوز است. این درخواست پارامترهایی را تعیین میکند که برنامه شما را شناسایی کرده و مجوزهایی را که از کاربر خواسته میشود به برنامه شما اعطا کند، تعریف میکند.
اگر از یک کتابخانه کلاینت گوگل برای احراز هویت و مجوز OAuth 2.0 استفاده میکنید، یک شیء ایجاد و پیکربندی میکنید که این پارامترها را تعریف میکند.
اگر مستقیماً نقطه پایانی Google OAuth 2.0 را فراخوانی کنید، یک URL ایجاد میکنید و پارامترها را روی آن URL تنظیم میکنید.
تبهای زیر پارامترهای مجوزدهی پشتیبانیشده برای برنامههای وب سرور را تعریف میکنند. مثالهای مختص زبان همچنین نحوه استفاده از یک کتابخانه کلاینت یا کتابخانه مجوزدهی را برای پیکربندی شیء که آن پارامترها را تنظیم میکند، نشان میدهند.
پی اچ پی
قطعه کد زیر یک شیء Google\Client() ایجاد میکند که پارامترهای درخواست مجوز را تعریف میکند.
آن شیء از اطلاعات فایل client_secret.json شما برای شناسایی برنامهتان استفاده میکند. (برای اطلاعات بیشتر در مورد آن فایل، به بخش ایجاد اعتبارنامههای مجوز مراجعه کنید.) این شیء همچنین محدودههایی را که برنامه شما درخواست دسترسی به آنها را دارد و URL مربوط به نقطه پایانی احراز هویت برنامه شما را شناسایی میکند، که پاسخ سرور OAuth 2.0 گوگل را مدیریت خواهد کرد. در نهایت، کد، پارامترهای اختیاری access_type و include_granted_scopes را تنظیم میکند.
برای مثال، این کد درخواست دسترسی آفلاین و فقط خواندنی به ابردادههای گوگل درایو و رویدادهای تقویم کاربر را میدهد:
use Google\Client;$client = new Client();// Required, call the setAuthConfig function to load authorization credentials from// client_secret.json file.$client->setAuthConfig('client_secret.json');// Required, to set the scope value, call the addScope function$client->addScope([Google\Service\Drive::DRIVE_METADATA_READONLY, Google\Service\Calendar::CALENDAR_READONLY]);// Required, call the setRedirectUri function to specify a valid redirect URI for the// provided client_id$client->setRedirectUri('http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php');// Recommended, offline access will give you both an access and refresh token so that// your app can refresh the access token without user interaction.$client->setAccessType('offline');// Recommended, call the setState function. Using a state value can increase your assurance that// an incoming connection is the result of an authentication request.$client->setState($sample_passthrough_value);// Optional, if your application knows which user is trying to authenticate, it can use this// parameter to provide a hint to the Google Authentication Server.$client->setLoginHint('hint@example.com');// Optional, call the setPrompt function to set "consent" will prompt the user for consent$client->setPrompt('consent');// Optional, call the setIncludeGrantedScopes function with true to enable incremental// authorization$client->setIncludeGrantedScopes(true);
پایتون
قطعه کد زیر از ماژول google-auth-oauthlib.flow برای ساخت درخواست مجوز استفاده میکند.
این کد یک شیء Flow میسازد که برنامه شما را با استفاده از اطلاعات فایل client_secret.json که پس از ایجاد اعتبارنامههای مجوز دانلود کردهاید، شناسایی میکند. این شیء همچنین محدودههایی را که برنامه شما درخواست دسترسی به آنها را دارد و URL مربوط به نقطه پایانی احراز هویت برنامه شما را شناسایی میکند که پاسخ سرور OAuth 2.0 گوگل را مدیریت خواهد کرد. در نهایت، کد پارامترهای اختیاری access_type و include_granted_scopes را تنظیم میکند.
برای مثال، این کد درخواست دسترسی آفلاین و فقط خواندنی به ابردادههای گوگل درایو و رویدادهای تقویم کاربر را میدهد:
importgoogle.oauth2.credentialsimportgoogle_auth_oauthlib.flow# Required, call the from_client_secrets_file method to retrieve the client ID from a# client_secret.json file. The client ID (from that file) and access scopes are required. (You can# also use the from_client_config method, which passes the client configuration as it originally# appeared in a client secrets file but doesn't access the file itself.)flow=google_auth_oauthlib.flow.Flow.from_client_secrets_file('client_secret.json',scopes=['https://www.googleapis.com/auth/drive.metadata.readonly','https://www.googleapis.com/auth/calendar.readonly'])# Required, indicate where the API server will redirect the user after the user completes# the authorization flow. The redirect URI is required. The value must exactly# match one of the authorized redirect URIs for the OAuth 2.0 client, which you# configured in the API Console. If this value doesn't match an authorized URI,# you will get a 'redirect_uri_mismatch' error.flow.redirect_uri='https://www.example.com/oauth2callback'# Generate URL for request to Google's OAuth 2.0 server.# Use kwargs to set optional request parameters.authorization_url,state=flow.authorization_url(# Recommended, enable offline access so that you can refresh an access token without# re-prompting the user for permission. Recommended for web server apps.access_type='offline',# Optional, enable incremental authorization. Recommended as a best practice.include_granted_scopes='true',# Optional, if your application knows which user is trying to authenticate, it can use this# parameter to provide a hint to the Google Authentication Server.login_hint='hint@example.com',# Optional, set prompt to 'consent' will prompt the user for consentprompt='consent')
روبی
از فایل client_secrets.json که ایجاد کردهاید برای پیکربندی یک شیء کلاینت در برنامه خود استفاده کنید. هنگام پیکربندی یک شیء کلاینت، محدودههایی را که برنامه شما باید به آنها دسترسی داشته باشد، به همراه URL به نقطه پایانی احراز هویت برنامه خود که پاسخ سرور OAuth 2.0 را مدیریت میکند، مشخص میکنید.
برای مثال، این کد درخواست دسترسی آفلاین و فقط خواندنی به ابردادههای گوگل درایو و رویدادهای تقویم کاربر را میدهد:
require'googleauth'require'googleauth/web_user_authorizer'require'googleauth/stores/redis_token_store'require'google/apis/drive_v3'require'google/apis/calendar_v3'# Required, call the from_file method to retrieve the client ID from a# client_secret.json file.client_id=Google::Auth::ClientId.from_file('/path/to/client_secret.json')# Required, scope value # Access scopes for two non-Sign-In scopes: Read-only Drive activity and Google Calendar.scope=['Google::Apis::DriveV3::AUTH_DRIVE_METADATA_READONLY','Google::Apis::CalendarV3::AUTH_CALENDAR_READONLY']# Required, Authorizers require a storage instance to manage long term persistence of# access and refresh tokens.token_store=Google::Auth::Stores::RedisTokenStore.new(redis:Redis.new)# Required, indicate where the API server will redirect the user after the user completes# the authorization flow. The redirect URI is required. The value must exactly# match one of the authorized redirect URIs for the OAuth 2.0 client, which you# configured in the API Console. If this value doesn't match an authorized URI,# you will get a 'redirect_uri_mismatch' error.callback_uri='/oauth2callback'# To use OAuth2 authentication, we need access to a CLIENT_ID, CLIENT_SECRET, AND REDIRECT_URI# from the client_secret.json file. To get these credentials for your application, visit# https://console.cloud.google.com/apis/credentials.authorizer=Google::Auth::WebUserAuthorizer.new(client_id,scope,token_store,callback_uri)
برنامه شما از شیء کلاینت برای انجام عملیات OAuth 2.0، مانند تولید URLهای درخواست مجوز و اعمال توکنهای دسترسی به درخواستهای HTTP، استفاده میکند.
نود جی اس
قطعه کد زیر یک شیء google.auth.OAuth2 ایجاد میکند که پارامترهای درخواست مجوز را تعریف میکند.
آن شیء از اطلاعات فایل client_secret.json شما برای شناسایی برنامهتان استفاده میکند. برای درخواست مجوز از یک کاربر برای بازیابی یک توکن دسترسی، او را به یک صفحه رضایت هدایت میکنید. برای ایجاد URL صفحه رضایت:
const{google}=require('googleapis');constcrypto=require('crypto');constexpress=require('express');constsession=require('express-session');/** * To use OAuth2 authentication, we need access to a CLIENT_ID, CLIENT_SECRET, AND REDIRECT_URI * from the client_secret.json file. To get these credentials for your application, visit * https://console.cloud.google.com/apis/credentials. */constoauth2Client=newgoogle.auth.OAuth2(YOUR_CLIENT_ID,YOUR_CLIENT_SECRET,YOUR_REDIRECT_URL);// Access scopes for two non-Sign-In scopes: Read-only Drive activity and Google Calendar.constscopes=['https://www.googleapis.com/auth/drive.metadata.readonly','https://www.googleapis.com/auth/calendar.readonly'];// Generate a secure random state value.conststate=crypto.randomBytes(32).toString('hex');// Store state in the sessionreq.session.state=state;// Generate a url that asks permissions for the Drive activity and Google Calendar scopeconstauthorizationUrl=oauth2Client.generateAuthUrl({// 'online' (default) or 'offline' (gets refresh_token)access_type:'offline',/** Pass in the scopes array defined above. * Alternatively, if only one scope is needed, you can pass a scope URL as a string */scope:scopes,// Enable incremental authorization. Recommended as a best practice.include_granted_scopes:true,// Include the state parameter to reduce the risk of CSRF attacks.state:state});
نکته مهم - refresh_token فقط در اولین مجوز بازگردانده میشود. جزئیات بیشتر اینجا .
HTTP/REST
نقطه پایانی OAuth 2.0 گوگل در آدرس https://accounts.google.com/o/oauth2/v2/auth قرار دارد. این نقطه پایانی فقط از طریق HTTPS قابل دسترسی است. اتصالات HTTP ساده رد میشوند.
سرور احراز هویت گوگل از پارامترهای رشته پرس و جوی زیر برای برنامههای وب سرور پشتیبانی میکند:
پارامترها
client_id
مورد نیاز
شناسه کلاینت برای برنامه شما. میتوانید این مقدار را در Cloud ConsoleClients page.
redirect_uri
مورد نیاز
تعیین میکند که سرور API پس از تکمیل جریان مجوز توسط کاربر، کاربر را به کجا هدایت کند. مقدار باید دقیقاً با یکی از URI های هدایت مجاز برای کلاینت OAuth 2.0 که در کلاینت خود پیکربندی کردهاید، مطابقت داشته باشد. Cloud ConsoleClients pageاگر این مقدار با یک URI تغییر مسیر مجاز برای client_id ارائه شده مطابقت نداشته باشد، خطای redirect_uri_mismatch دریافت خواهید کرد.
توجه داشته باشید که طرح http یا https ، بزرگی و کوچکی حروف و اسلش انتهایی (' / ') باید همگی مطابقت داشته باشند.
response_type
مورد نیاز
تعیین میکند که آیا نقطه پایانی Google OAuth 2.0 کد مجوز را برمیگرداند یا خیر.
مقدار پارامتر را برای برنامههای وب سرور روی code تنظیم کنید.
scope
مورد نیاز
فهرستی از محدودهها که با فاصله از هم جدا شدهاند و منابعی را که برنامه شما میتواند از طرف کاربر به آنها دسترسی داشته باشد، مشخص میکنند. این مقادیر، صفحه رضایتنامهای را که گوگل به کاربر نمایش میدهد، مشخص میکنند.
محدودهها به برنامه شما این امکان را میدهند که فقط به منابعی که نیاز دارد درخواست دسترسی کند و در عین حال کاربران را قادر میسازد میزان دسترسی که به برنامه شما میدهند را کنترل کنند. بنابراین، بین تعداد محدودههای درخواستی و احتمال کسب رضایت کاربر، رابطه معکوس وجود دارد.
توصیه میکنیم برنامه شما در صورت امکان، درخواست دسترسی به حوزههای مجوز را در context ارائه دهد. با درخواست دسترسی به دادههای کاربر در context، با استفاده از مجوز افزایشی ، به کاربران کمک میکنید تا بفهمند که چرا برنامه شما به دسترسی مورد درخواست خود نیاز دارد.
access_type
توصیه شده
نشان میدهد که آیا برنامه شما میتواند توکنهای دسترسی را هنگامی که کاربر در مرورگر حضور ندارد، بهروزرسانی کند یا خیر. مقادیر معتبر پارامتر، online که مقدار پیشفرض است و offline هستند.
اگر برنامه شما نیاز دارد که توکنهای دسترسی را در زمانی که کاربر در مرورگر حضور ندارد، بهروزرسانی کند، مقدار را روی offline تنظیم کنید. این روش بهروزرسانی توکنهای دسترسی است که بعداً در این سند توضیح داده خواهد شد. این مقدار به سرور مجوز گوگل دستور میدهد که اولین باری که برنامه شما کد مجوز را با توکنها مبادله میکند، یک توکن بهروزرسانی و یک توکن دسترسی را برگرداند.
state
توصیه شده
هر مقدار رشتهای را که برنامه شما برای حفظ وضعیت بین درخواست مجوز شما و پاسخ سرور مجوز استفاده میکند، مشخص میکند. سرور پس از اینکه کاربر درخواست دسترسی برنامه شما را تأیید یا رد کرد، مقدار دقیقی را که شما به عنوان یک جفت name=value در مؤلفه پرس و جوی URL ( ? ) از redirect_uri ارسال میکنید، برمیگرداند.
شما میتوانید از این پارامتر برای چندین هدف استفاده کنید، مانند هدایت کاربر به منبع صحیح در برنامهتان، ارسال nonceها و کاهش جعل درخواست بین سایتی. از آنجایی که redirect_uri شما قابل حدس زدن است، استفاده از مقدار state میتواند اطمینان شما را از اینکه اتصال ورودی نتیجه یک درخواست احراز هویت است، افزایش دهد. اگر یک رشته تصادفی ایجاد کنید یا هش یک کوکی یا مقدار دیگری را که وضعیت کلاینت را ثبت میکند، کدگذاری کنید، میتوانید پاسخ را اعتبارسنجی کنید تا علاوه بر این، اطمینان حاصل شود که درخواست و پاسخ از یک مرورگر سرچشمه گرفتهاند و در برابر حملاتی مانند جعل درخواست بین سایتی محافظت ایجاد کنید. برای مثالی از نحوه ایجاد و تأیید یک توکن state ، به مستندات OpenID Connect مراجعه کنید.
include_granted_scopes
اختیاری
برنامهها را قادر میسازد تا از مجوز افزایشی برای درخواست دسترسی به حوزههای اضافی در متن استفاده کنند. اگر مقدار این پارامتر را روی true تنظیم کنید و درخواست مجوز اعطا شود، توکن دسترسی جدید، هر حوزهای را که کاربر قبلاً به برنامه دسترسی داده است، پوشش میدهد. برای مثالها به بخش مجوز افزایشی مراجعه کنید.
enable_granular_consent
اختیاری
پیشفرض روی true است. اگر روی false تنظیم شود، مجوزهای جزئیتر حساب گوگل برای شناسههای کلاینت OAuth که قبل از سال ۲۰۱۹ ایجاد شدهاند غیرفعال میشوند. برای شناسههای کلاینت OAuth جدیدتر تأثیری ندارد، زیرا مجوزهای جزئیتر همیشه برای آنها فعال است.
وقتی گوگل مجوزهای جزئی را برای یک برنامه فعال میکند، این پارامتر دیگر هیچ تاثیری نخواهد داشت.
login_hint
اختیاری
اگر برنامه شما بداند کدام کاربر در حال تلاش برای احراز هویت است، میتواند از این پارامتر برای ارائه یک راهنما به سرور احراز هویت گوگل استفاده کند. سرور از این راهنما برای سادهسازی جریان ورود به سیستم، یا با پر کردن فیلد ایمیل در فرم ورود به سیستم یا با انتخاب جلسه ورود چندگانه مناسب، استفاده میکند.
مقدار پارامتر را روی یک آدرس ایمیل یا شناسه sub تنظیم کنید، که معادل شناسه گوگل کاربر است.
prompt
اختیاری
فهرستی از درخواستها که با فاصله از هم جدا شده و به حروف کوچک و بزرگ حساس هستند و کاربر را نمایش میدهند. اگر این پارامتر را مشخص نکنید، فقط در اولین باری که پروژه شما درخواست دسترسی میدهد، از کاربر درخواست میشود. برای اطلاعات بیشتر به بخش درخواست رضایت مجدد مراجعه کنید.
مقادیر ممکن عبارتند از:
none
هیچ صفحه احراز هویت یا رضایتی نمایش داده نشود. نباید با مقادیر دیگری مشخص شود.
consent
از کاربر رضایتنامه دریافت کنید.
select_account
از کاربر بخواهید یک حساب کاربری انتخاب کند.
مرحله ۲: هدایت به سرور OAuth 2.0 گوگل
کاربر را به سرور OAuth 2.0 گوگل هدایت کنید تا فرآیند احراز هویت و مجوزدهی آغاز شود. معمولاً این اتفاق زمانی میافتد که برنامه شما ابتدا نیاز به دسترسی به دادههای کاربر دارد. در مورد مجوزدهی افزایشی ، این مرحله همچنین زمانی رخ میدهد که برنامه شما ابتدا نیاز به دسترسی به منابع اضافی دارد که هنوز مجوز دسترسی به آنها را ندارد.
پی اچ پی
یک URL برای درخواست دسترسی از سرور OAuth 2.0 گوگل ایجاد کنید:
پس از ایجاد URL درخواست، کاربر را به آن هدایت کنید.
سرور OAuth 2.0 گوگل، کاربر را احراز هویت میکند و رضایت او را برای دسترسی برنامه شما به محدودههای درخواستی دریافت میکند. پاسخ با استفاده از URL تغییر مسیری که مشخص کردهاید، به برنامه شما ارسال میشود.
مرحله ۳: گوگل از کاربر رضایت میخواهد
در این مرحله، کاربر تصمیم میگیرد که آیا به برنامه شما دسترسی مورد درخواست را اعطا کند یا خیر. در این مرحله، گوگل یک پنجره رضایتنامه نمایش میدهد که نام برنامه شما و سرویسهای API گوگل که درخواست مجوز دسترسی به آنها را دارد، به همراه اطلاعات احراز هویت کاربر و خلاصهای از محدودههای دسترسی که باید اعطا شود را نشان میدهد. سپس کاربر میتواند با اعطای دسترسی به یک یا چند محدوده درخواستی برنامه شما موافقت کند یا درخواست را رد کند.
برنامه شما در این مرحله نیازی به انجام کاری ندارد، زیرا منتظر پاسخ از سرور OAuth 2.0 گوگل است که نشان میدهد آیا دسترسی اعطا شده است یا خیر. این پاسخ در مرحله بعد توضیح داده شده است.
خطاها
درخواستها به نقطه پایانی احراز هویت OAuth 2.0 گوگل ممکن است به جای جریانهای احراز هویت و مجوز مورد انتظار، پیامهای خطای کاربرپسند را نمایش دهند. کدهای خطای رایج و راهحلهای پیشنهادی عبارتند از:
admin_policy_enforced
حساب گوگل به دلیل سیاستهای مدیر Google Workspace خود قادر به تأیید یک یا چند محدوده درخواستی نیست. برای اطلاعات بیشتر در مورد اینکه چگونه یک مدیر میتواند دسترسی به همه محدودهها یا محدودههای حساس و محدود شده را تا زمانی که دسترسی به طور صریح به شناسه کلاینت OAuth شما اعطا نشده باشد، محدود کند، به مقاله راهنمای مدیریت Google Workspace با عنوان «کنترل دسترسی برنامههای شخص ثالث و داخلی به دادههای Google Workspace» مراجعه کنید.
disallowed_useragent
نقطه پایانی احراز هویت درون یک عامل کاربری تعبیهشده نمایش داده میشود که توسط سیاستهای OAuth 2.0 گوگل مجاز نیست.
توسعهدهندگان iOS و macOS ممکن است هنگام باز کردن درخواستهای مجوز در WKWebView با این خطا مواجه شوند. توسعهدهندگان باید به جای آن از کتابخانههای iOS مانند Google Sign-In برای iOS یا OpenID Foundation’s AppAuth برای iOS استفاده کنند.
توسعهدهندگان وب ممکن است زمانی که یک برنامه iOS یا macOS یک لینک وب عمومی را در یک عامل کاربر تعبیهشده باز میکند و کاربر از سایت شما به نقطه پایانی مجوز OAuth 2.0 گوگل هدایت میشود، با این خطا مواجه شوند. توسعهدهندگان باید اجازه دهند لینکهای عمومی در کنترلکننده لینک پیشفرض سیستم عامل، که شامل کنترلکنندههای لینک جهانی یا برنامه مرورگر پیشفرض است، باز شوند. کتابخانه SFSafariViewController نیز یک گزینه پشتیبانی شده است.
org_internal
شناسه کلاینت OAuth در درخواست، بخشی از پروژهای است که دسترسی به حسابهای گوگل را در یک سازمان ابری خاص گوگل محدود میکند. برای اطلاعات بیشتر در مورد این گزینه پیکربندی، به بخش نوع کاربر در مقاله راهنمای تنظیم صفحه رضایت OAuth خود مراجعه کنید.
invalid_client
رمز کلاینت OAuth نادرست است. پیکربندی کلاینت OAuth ، از جمله شناسه کلاینت و رمز استفاده شده برای این درخواست را بررسی کنید.
deleted_client
کلاینت OAuth که برای ایجاد درخواست استفاده شده بود، حذف شده است. حذف میتواند به صورت دستی یا خودکار در مورد کلاینتهای بلااستفاده انجام شود. کلاینتهای حذف شده را میتوان ظرف 30 روز از زمان حذف بازیابی کرد. اطلاعات بیشتر .
invalid_grant
هنگام بهروزرسانی توکن دسترسی یا استفاده از مجوز افزایشی ، ممکن است توکن منقضی شده یا نامعتبر شده باشد. کاربر را دوباره احراز هویت کنید و برای دریافت توکنهای جدید، رضایت کاربر را جویا شوید. اگر همچنان این خطا را مشاهده میکنید، مطمئن شوید که برنامه شما به درستی پیکربندی شده است و از توکنها و پارامترهای صحیح در درخواست خود استفاده میکنید. در غیر این صورت، ممکن است حساب کاربری حذف یا غیرفعال شده باشد.
redirect_uri_mismatch
redirect_uri ارسال شده در درخواست مجوز با یک URI تغییر مسیر مجاز برای شناسه کلاینت OAuth مطابقت ندارد. URI های تغییر مسیر مجاز را در Google Cloud ConsoleClients page.
پارامتر redirect_uri ممکن است به جریان OAuth out-of-band (OOB) اشاره داشته باشد که منسوخ شده و دیگر پشتیبانی نمیشود. برای بهروزرسانی ادغام خود به راهنمای مهاجرت مراجعه کنید.
invalid_request
درخواستی که ارائه دادید، مشکلی داشت. این مشکل میتواند به دلایل مختلفی باشد:
درخواست به درستی قالب بندی نشده است
درخواست پارامترهای مورد نیاز را نداشت
این درخواست از روش احراز هویتی استفاده میکند که گوگل از آن پشتیبانی نمیکند. تأیید کنید که ادغام OAuth شما از روش ادغام توصیهشده استفاده میکند.
مرحله ۴: مدیریت پاسخ سرور OAuth 2.0
سرور OAuth 2.0 با استفاده از URL مشخص شده در درخواست، به درخواست دسترسی برنامه شما پاسخ میدهد.
اگر کاربر درخواست دسترسی را تأیید کند، پاسخ حاوی یک کد مجوز است. اگر کاربر درخواست را تأیید نکند، پاسخ حاوی یک پیام خطا است. کد مجوز یا پیام خطایی که به وب سرور بازگردانده میشود، در رشته پرسوجو، همانطور که در زیر نشان داده شده است، ظاهر میشود:
شما میتوانید این جریان را با کلیک روی نمونه URL زیر که دسترسی فقط خواندنی برای مشاهده فرادادههای فایلهای گوگل درایو شما و دسترسی فقط خواندنی برای مشاهده رویدادهای تقویم گوگل شما را درخواست میکند، آزمایش کنید:
پس از تکمیل جریان OAuth 2.0، مرورگر شما را به OAuth 2.0 Playground ، ابزاری برای آزمایش جریانهای OAuth، هدایت میکند. خواهید دید که OAuth 2.0 Playground به طور خودکار کد مجوز را دریافت کرده است.
مرحله ۵: کد مجوز را با توکنهای بهروزرسانی و دسترسی مبادله کنید
پس از اینکه وب سرور کد مجوز را دریافت کرد، میتواند کد مجوز را با یک توکن دسترسی (access token) مبادله کند.
پی اچ پی
برای تبادل یک کد مجوز با یک توکن دسترسی، از متد fetchAccessTokenWithAuthCode استفاده کنید:
در صفحه فراخوانی خود، از کتابخانه google-auth برای تأیید پاسخ سرور احراز هویت استفاده کنید. سپس، از متد flow.fetch_token برای تبادل کد احراز هویت در آن پاسخ با یک توکن دسترسی استفاده کنید:
state=flask.session['state']flow=google_auth_oauthlib.flow.Flow.from_client_secrets_file('client_secret.json',scopes=['https://www.googleapis.com/auth/drive.metadata.readonly'],state=state)flow.redirect_uri=flask.url_for('oauth2callback',_external=True)authorization_response=flask.request.urlflow.fetch_token(authorization_response=authorization_response)# Store the credentials in browser session storage, but for security: client_id, client_secret,# and token_uri are instead stored only on the backend server.credentials=flow.credentialsflask.session['credentials']={'token':credentials.token,'refresh_token':credentials.refresh_token,'granted_scopes':credentials.granted_scopes}
روبی
در صفحه فراخوانی خود، از کتابخانه googleauth برای تأیید پاسخ سرور احراز هویت استفاده کنید. از متد authorizer.handle_auth_callback_deferred برای ذخیره کد احراز هویت و هدایت مجدد به URL که در ابتدا درخواست احراز هویت کرده بود، استفاده کنید. این کار با ذخیره موقت نتایج در جلسه کاربر، تبادل کد را به تعویق میاندازد.
برای تبادل کد مجوز با یک توکن دسترسی، از متد getToken استفاده کنید:
consturl=require('url');// Receive the callback from Google's OAuth 2.0 server.app.get('/oauth2callback',async(req,res)=>{letq=url.parse(req.url,true).query;if(q.error){// An error response e.g. error=access_deniedconsole.log('Error:'+q.error);}elseif(q.state!==req.session.state){//check state valueconsole.log('State mismatch. Possible CSRF attack');res.end('State mismatch. Possible CSRF attack');}else{// Get access and refresh tokens (if access_type is offline)let{tokens}=awaitoauth2Client.getToken(q.code);oauth2Client.setCredentials(tokens);});
HTTP/REST
برای تبادل کد مجوز با یک توکن دسترسی، با نقطه پایانی https://oauth2.googleapis.com/token تماس بگیرید و پارامترهای زیر را تنظیم کنید:
فیلدها
client_id
شناسه کلاینت به دست آمده از Cloud ConsoleClients page.
client_secret
اختیاری
راز مشتری که از ... به دست آمده است Cloud ConsoleClients page.
گوگل با بازگرداندن یک شیء JSON که حاوی یک توکن دسترسی کوتاهمدت و یک توکن بهروزرسانی است، به این درخواست پاسخ میدهد. توجه داشته باشید که توکن بهروزرسانی فقط در صورتی بازگردانده میشود که برنامه شما پارامتر access_type را در درخواست اولیه به سرور تأیید گوگل،offline تنظیم کرده باشد.
پاسخ شامل فیلدهای زیر است:
فیلدها
access_token
توکنی که برنامه شما برای تأیید درخواست API گوگل ارسال میکند.
expires_in
طول عمر باقی مانده از توکن دسترسی بر حسب ثانیه.
refresh_token
توکنی که میتوانید از آن برای دریافت یک توکن دسترسی جدید استفاده کنید. توکنهای تازهسازی تا زمانی که کاربر دسترسی را لغو کند یا توکن تازهسازی منقضی شود، معتبر هستند. باز هم، این فیلد فقط در صورتی در این پاسخ وجود دارد که پارامتر access_type را در درخواست اولیه به سرور مجوز گوگل، روی offline تنظیم کرده باشید.
refresh_token_expires_in
طول عمر باقیماندهی توکن بهروزرسانی بر حسب ثانیه. این مقدار فقط زمانی تنظیم میشود که کاربر دسترسی مبتنی بر زمان را اعطا کند.
scope
دامنههای دسترسی اعطا شده توسط access_token به صورت فهرستی از رشتههای جدا شده با فاصله و حساس به حروف بزرگ و کوچک بیان میشوند.
token_type
نوع توکن برگشتی. در حال حاضر، مقدار این فیلد همیشه روی Bearer تنظیم میشود.
هنگام تعویض کد مجوز با یک توکن دسترسی، ممکن است به جای پاسخ مورد انتظار با خطای زیر مواجه شوید. کدهای خطای رایج و راهحلهای پیشنهادی در زیر فهرست شدهاند.
invalid_grant
کد مجوز ارائه شده نامعتبر است یا فرمت آن اشتباه است. با راهاندازی مجدد فرآیند OAuth، کد جدیدی درخواست کنید تا دوباره از کاربر رضایت بخواهد.
مرحله ۶: بررسی کنید که کاربران کدام حوزهها را اعطا کردهاند
هنگام درخواست چندین مجوز (اسکوپ)، کاربران ممکن است به برنامه شما اجازه دسترسی به همه آنها را ندهند. برنامه شما باید تأیید کند که کدام اسکوپها واقعاً اعطا شدهاند و به طور مناسب موقعیتهایی را که برخی از مجوزها رد میشوند، مدیریت کند، معمولاً با غیرفعال کردن ویژگیهایی که به آن اسکوپهای رد شده متکی هستند.
با این حال، استثنائاتی نیز وجود دارد. برنامههای Google Workspace Enterprise با تفویض اختیار در سطح دامنه یا برنامههایی که به عنوان Trusted علامتگذاری شدهاند، صفحه رضایت مجوزهای جزئی را دور میزنند. برای این برنامهها، کاربران صفحه رضایت مجوزهای جزئی را نمیبینند. در عوض، برنامه شما یا همه محدودههای درخواستی را دریافت میکند یا هیچ کدام را دریافت نمیکند.
برای بررسی اینکه کاربر کدام حوزهها را اعطا کرده است، از متد getGrantedScope() استفاده کنید:
// Space-separated string of granted scopes if it exists, otherwise null.$granted_scopes = $client->getOAuth2Service()->getGrantedScope();// Determine which scopes user granted and build a dictionary$granted_scopes_dict = [ 'Drive' => str_contains($granted_scopes, Google\Service\Drive::DRIVE_METADATA_READONLY), 'Calendar' => str_contains($granted_scopes, Google\Service\Calendar::CALENDAR_READONLY)];
پایتون
شیء credentials برگردانده شده دارای یک ویژگی granted_scopes است که لیستی از حوزههایی است که کاربر به برنامه شما اعطا کرده است.
هنگام درخواست چندین حوزه به طور همزمان، بررسی کنید که کدام حوزهها از طریق ویژگی scope شیء credentials اعطا شدهاند.
# User authorized the request. Now, check which scopes were granted.ifcredentials.scope.include?(Google::Apis::DriveV3::AUTH_DRIVE_METADATA_READONLY)# User authorized read-only Drive activity permission.# Calling the APIs, etcelse# User didn't authorize read-only Drive activity permission.# Update UX and application accordinglyend# Check if user authorized Calendar read permission.ifcredentials.scope.include?(Google::Apis::CalendarV3::AUTH_CALENDAR_READONLY)# User authorized Calendar read permission.# Calling the APIs, etc.else# User didn't authorize Calendar read permission.# Update UX and application accordinglyend
نود جی اس
هنگام درخواست چندین حوزه به طور همزمان، بررسی کنید که کدام حوزهها از طریق ویژگی scope شیء tokens اعطا شدهاند.
// User authorized the request. Now, check which scopes were granted.if(tokens.scope.includes('https://www.googleapis.com/auth/drive.metadata.readonly')){// User authorized read-only Drive activity permission.// Calling the APIs, etc.}else{// User didn't authorize read-only Drive activity permission.// Update UX and application accordingly}// Check if user authorized Calendar read permission.if(tokens.scope.includes('https://www.googleapis.com/auth/calendar.readonly')){// User authorized Calendar read permission.// Calling the APIs, etc.}else{// User didn't authorize Calendar read permission.// Update UX and application accordingly}
HTTP/REST
برای بررسی اینکه آیا کاربر به برنامه شما دسترسی به یک محدوده خاص را اعطا کرده است یا خیر، فیلد scope را در پاسخ access token بررسی کنید. محدودههای دسترسی اعطا شده توسط access_token به صورت لیستی از رشتههای حساس به حروف بزرگ و کوچک و جدا از فاصله بیان میشوند.
برای مثال، نمونه پاسخ توکن دسترسی زیر نشان میدهد که کاربر به برنامه شما دسترسی به مجوزهای فعالیت Drive فقط خواندنی و رویدادهای Calendar را اعطا کرده است:
با انجام مراحل زیر، از توکن دسترسی برای فراخوانی APIهای گوگل استفاده کنید:
اگر نیاز دارید که یک توکن دسترسی را به یک شیء جدید Google\Client اعمال کنید - برای مثال، اگر توکن دسترسی را در یک جلسه کاربر ذخیره کردهاید - از متد setAccessToken استفاده کنید:
$client->setAccessToken($access_token);
یک شیء سرویس برای API که میخواهید فراخوانی کنید، بسازید. شما با ارائه یک شیء مجاز Google\Client به سازنده API که میخواهید فراخوانی کنید، یک شیء سرویس میسازید. برای مثال، برای فراخوانی Drive API:
$drive = new Google\Service\Drive($client);
با استفاده از رابط ارائه شده توسط شیء سرویس، درخواستهایی را به سرویس API ارسال کنید. به عنوان مثال، برای فهرست کردن فایلهای موجود در گوگل درایو کاربر احراز هویت شده:
$files = $drive->files->listFiles(array());
پایتون
پس از دریافت یک توکن دسترسی، برنامه شما میتواند از آن توکن برای تأیید درخواستهای API از طرف یک حساب کاربری یا حساب سرویس مشخص استفاده کند. از اعتبارنامههای تأیید مختص کاربر برای ساخت یک شیء سرویس برای API که میخواهید فراخوانی کنید استفاده کنید و سپس از آن شیء برای ارسال درخواستهای API مجاز استفاده کنید.
یک شیء سرویس برای API که میخواهید فراخوانی کنید، بسازید. شما با فراخوانی متد build کتابخانه googleapiclient.discovery به همراه نام و نسخه API و اطلاعات کاربری، یک شیء سرویس میسازید: به عنوان مثال، برای فراخوانی نسخه ۳ از Drive API:
با استفاده از رابط ارائه شده توسط شیء سرویس، درخواستهایی را به سرویس API ارسال کنید. به عنوان مثال، برای فهرست کردن فایلهای موجود در گوگل درایو کاربر احراز هویت شده:
files=drive.files().list().execute()
روبی
پس از دریافت یک توکن دسترسی، برنامه شما میتواند از آن توکن برای ارسال درخواستهای API از طرف یک حساب کاربری یا حساب سرویس مشخص استفاده کند. از اعتبارنامههای مجوزدهی مختص کاربر برای ساخت یک شیء سرویس برای API که میخواهید فراخوانی کنید استفاده کنید و سپس از آن شیء برای ارسال درخواستهای API مجاز استفاده کنید.
یک شیء سرویس برای API که میخواهید فراخوانی کنید، بسازید. برای مثال، برای فراخوانی نسخه ۳ از Drive API:
drive=Google::Apis::DriveV3::DriveService.new
اعتبارنامهها را روی سرویس تنظیم کنید:
drive.authorization=credentials
با استفاده از رابط ارائه شده توسط شیء سرویس، درخواستهایی را به سرویس API ارسال کنید. به عنوان مثال، برای فهرست کردن فایلهای موجود در گوگل درایو کاربر احراز هویت شده:
files=drive.list_files
به طور جایگزین، میتوان با ارائه پارامتر options به یک متد، مجوزدهی را بر اساس هر متد ارائه داد:
پس از دریافت یک توکن دسترسی و تنظیم آن روی شیء OAuth2 ، از این شیء برای فراخوانی APIهای گوگل استفاده کنید. برنامه شما میتواند از آن توکن برای تأیید درخواستهای API از طرف یک حساب کاربری یا حساب سرویس مشخص استفاده کند. یک شیء سرویس برای API که میخواهید فراخوانی کنید، بسازید. به عنوان مثال، کد زیر از API گوگل درایو برای فهرست کردن نام فایلهای موجود در درایو کاربر استفاده میکند.
const{google}=require('googleapis');// Example of using Google Drive API to list filenames in user's Drive.constdrive=google.drive('v3');drive.files.list({auth:oauth2Client,pageSize:10,fields:'nextPageToken, files(id, name)',},(err1,res1)=>{if(err1)returnconsole.log('The API returned an error: '+err1);constfiles=res1.data.files;if(files.length){console.log('Files:');files.map((file)=>{console.log(`${file.name} (${file.id})`);});}else{console.log('No files found.');}});
HTTP/REST
After your application obtains an access token, you can use the token to make calls to a Google API on behalf of a given user account if the scope(s) of access required by the API have been granted. To do this, include the access token in a request to the API by including either an access_token query parameter or an Authorization HTTP header Bearer value. When possible, the HTTP header is preferable, because query strings tend to be visible in server logs. In most cases you can use a client library to set up your calls to Google APIs (for example, when calling the Drive Files API ).
You can try out all the Google APIs and view their scopes at the OAuth 2.0 Playground .
HTTP GET examples
A call to the drive.files endpoint (the Drive Files API) using the Authorization: Bearer HTTP header might look like the following. Note that you need to specify your own access token:
GET /drive/v2/files HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer access_token
Here is a call to the same API for the authenticated user using the access_token query string parameter:
GET https://www.googleapis.com/drive/v2/files?access_token=access_token
curl examples
You can test these commands with the curl command-line application. Here's an example that uses the HTTP header option (preferred):
The following example prints a JSON-formatted list of files in a user's Google Drive after the user authenticates and gives consent for the application to access the user's Drive metadata.
پی اچ پی
To run this example:
در API Console, add the URL of the local machine to the list of redirect URLs. For example, add http://localhost:8080 .
Create a new directory and change to it. For example:
mkdir ~/php-oauth2-example
cd ~/php-oauth2-example
Create the files index.php and oauth2callback.php with the following content.
Run the example with the PHP's built-in test web server:
php -S localhost:8080 ~/php-oauth2-example
فهرست.php
<?phprequire_once __DIR__.'/vendor/autoload.php';session_start();$client = new Google\Client();$client->setAuthConfig('client_secret.json');// User granted permission as an access token is in the session.if (isset($_SESSION['access_token']) && $_SESSION['access_token']){ $client->setAccessToken($_SESSION['access_token']); // Check if user granted Drive permission if ($_SESSION['granted_scopes_dict']['Drive']) { echo "Drive feature is enabled."; echo "</br>"; $drive = new Drive($client); $files = array(); $response = $drive->files->listFiles(array()); foreach ($response->files as $file) { echo "File: " . $file->name . " (" . $file->id . ")"; echo "</br>"; } } else { echo "Drive feature is NOT enabled."; echo "</br>"; } // Check if user granted Calendar permission if ($_SESSION['granted_scopes_dict']['Calendar']) { echo "Calendar feature is enabled."; echo "</br>"; } else { echo "Calendar feature is NOT enabled."; echo "</br>"; }}else{ // Redirect users to outh2call.php which redirects users to Google OAuth 2.0 $redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php'; header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));}?>
oauth2callback.php
<?phprequire_once __DIR__.'/vendor/autoload.php';session_start();$client = new Google\Client();// Required, call the setAuthConfig function to load authorization credentials from// client_secret.json file.$client->setAuthConfigFile('client_secret.json');$client->setRedirectUri('http://' . $_SERVER['HTTP_HOST']. $_SERVER['PHP_SELF']);// Required, to set the scope value, call the addScope function.$client->addScope([Google\Service\Drive::DRIVE_METADATA_READONLY, Google\Service\Calendar::CALENDAR_READONLY]);// Enable incremental authorization. Recommended as a best practice.$client->setIncludeGrantedScopes(true);// Recommended, offline access will give you both an access and refresh token so that// your app can refresh the access token without user interaction.$client->setAccessType("offline");// Generate a URL for authorization as it doesn't contain code and errorif (!isset($_GET['code']) && !isset($_GET['error'])){ // Generate and set state value $state = bin2hex(random_bytes(16)); $client->setState($state); $_SESSION['state'] = $state; // Generate a url that asks permissions. $auth_url = $client->createAuthUrl(); header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));}// User authorized the request and authorization code is returned to exchange access and// refresh tokens.if (isset($_GET['code'])){ // Check the state value if (!isset($_GET['state']) || $_GET['state'] !== $_SESSION['state']) { die('State mismatch. Possible CSRF attack.'); } // Get access and refresh tokens (if access_type is offline) $token = $client->fetchAccessTokenWithAuthCode($_GET['code']); /** Save access and refresh token to the session variables. * ACTION ITEM: In a production app, you likely want to save the * refresh token in a secure persistent storage instead. */ $_SESSION['access_token'] = $token; $_SESSION['refresh_token'] = $client->getRefreshToken(); // Space-separated string of granted scopes if it exists, otherwise null. $granted_scopes = $client->getOAuth2Service()->getGrantedScope(); // Determine which scopes user granted and build a dictionary $granted_scopes_dict = [ 'Drive' => str_contains($granted_scopes, Google\Service\Drive::DRIVE_METADATA_READONLY), 'Calendar' => str_contains($granted_scopes, Google\Service\Calendar::CALENDAR_READONLY) ]; $_SESSION['granted_scopes_dict'] = $granted_scopes_dict; $redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . '/'; header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));}// An error response e.g. error=access_deniedif (isset($_GET['error'])){ echo "Error: ". $_GET['error'];}?>
پایتون
This example uses the Flask framework. It runs a web application at http://localhost:8080 that lets you test the OAuth 2.0 flow. If you go to that URL, you should see five links:
Call Drive API: This link points to a page that tries to execute a sample API request if users granted the permission. If necessary, it starts the authorization flow. If successful, the page displays the API response.
Mock page to call Calendar API: This link points to a maockpage that tries to execute a sample Calendar API request if users granted the permission. If necessary, it starts the authorization flow. If successful, the page displays the API response.
Test the auth flow directly: This link points to a page that tries to send the user through the authorization flow . The app requests permission to submit authorized API requests on the user's behalf.
Revoke current credentials: This link points to a page that revokes permissions that the user has already granted to the application.
Clear Flask session credentials: This link clears authorization credentials that are stored in the Flask session. This lets you see what would happen if a user who had already granted permission to your app tried to execute an API request in a new session. It also lets you see the API response your app would get if a user had revoked permissions granted to your app, and your app still tried to authorize a request with a revoked access token.
# -*- coding: utf-8 -*-importosimportflaskimportjsonimportrequestsimportgoogle.oauth2.credentialsimportgoogle_auth_oauthlib.flowimportgoogleapiclient.discovery# This variable specifies the name of a file that contains the OAuth 2.0# information for this application, including its client_id and client_secret.CLIENT_SECRETS_FILE="client_secret.json"# The OAuth 2.0 access scope allows for access to the# authenticated user's account and requires requests to use an SSL connection.SCOPES=['https://www.googleapis.com/auth/drive.metadata.readonly','https://www.googleapis.com/auth/calendar.readonly']API_SERVICE_NAME='drive'API_VERSION='v2'app=flask.Flask(__name__)# Note: A secret key is included in the sample so that it works.# If you use this code in your application, replace this with a truly secret# key. See https://flask.palletsprojects.com/quickstart/#sessions.app.secret_key='REPLACE ME - this value is here as a placeholder.'@app.route('/')defindex():returnprint_index_table()@app.route('/drive')defdrive_api_request():if'credentials'notinflask.session:returnflask.redirect('authorize')features=flask.session['features']iffeatures['drive']:# Load client secrets from the server-side file.withopen(CLIENT_SECRETS_FILE,'r')asf:client_config=json.load(f)['web']# Load user-specific credentials from browser session storage.session_credentials=flask.session['credentials']# Reconstruct the credentials object.credentials=google.oauth2.credentials.Credentials(refresh_token=session_credentials.get('refresh_token'),scopes=session_credentials.get('granted_scopes'),token=session_credentials.get('token'),client_id=client_config.get('client_id'),client_secret=client_config.get('client_secret'),token_uri=client_config.get('token_uri'))drive=googleapiclient.discovery.build(API_SERVICE_NAME,API_VERSION,credentials=credentials)files=drive.files().list().execute()# Save credentials back to session in case access token was refreshed.flask.session['credentials']=credentials_to_dict(credentials)returnflask.jsonify(**files)else:# User didn't authorize read-only Drive activity permission.return'<p>Drive feature is not enabled.</p>'@app.route('/calendar')defcalendar_api_request():if'credentials'notinflask.session:returnflask.redirect('authorize')features=flask.session['features']iffeatures['calendar']:# User authorized Calendar read permission.# Calling the APIs, etc.return('<p>User granted the Google Calendar read permission. '+'This sample code does not include code to call Calendar</p>')else:# User didn't authorize Calendar read permission.# Update UX and application accordinglyreturn'<p>Calendar feature is not enabled.</p>'@app.route('/authorize')defauthorize():# Create flow instance to manage the OAuth 2.0 Authorization Grant Flow steps.flow=google_auth_oauthlib.flow.Flow.from_client_secrets_file(CLIENT_SECRETS_FILE,scopes=SCOPES)# The URI created here must exactly match one of the authorized redirect URIs# for the OAuth 2.0 client, which you configured in the API Console. If this# value doesn't match an authorized URI, you will get a 'redirect_uri_mismatch'# error.flow.redirect_uri=flask.url_for('oauth2callback',_external=True)authorization_url,state=flow.authorization_url(# Enable offline access so that you can refresh an access token without# re-prompting the user for permission. Recommended for web server apps.access_type='offline',# Enable incremental authorization. Recommended as a best practice.include_granted_scopes='true')# Store the state so the callback can verify the auth server response.flask.session['state']=statereturnflask.redirect(authorization_url)@app.route('/oauth2callback')defoauth2callback():# Specify the state when creating the flow in the callback so that it can# verified in the authorization server response.state=flask.session['state']flow=google_auth_oauthlib.flow.Flow.from_client_secrets_file(CLIENT_SECRETS_FILE,scopes=SCOPES,state=state)flow.redirect_uri=flask.url_for('oauth2callback',_external=True)# Use the authorization server's response to fetch the OAuth 2.0 tokens.authorization_response=flask.request.urlflow.fetch_token(authorization_response=authorization_response)# Store credentials in the session.# ACTION ITEM: In a production app, you likely want to save these# credentials in a persistent database instead.credentials=flow.credentialscredentials=credentials_to_dict(credentials)flask.session['credentials']=credentials# Check which scopes user grantedfeatures=check_granted_scopes(credentials)flask.session['features']=featuresreturnflask.redirect('/')@app.route('/revoke')defrevoke():if'credentials'notinflask.session:return('You need to <a href="/authorize">authorize</a> before '+'testing the code to revoke credentials.')# Load client secrets from the server-side file.withopen(CLIENT_SECRETS_FILE,'r')asf:client_config=json.load(f)['web']# Load user-specific credentials from the session.session_credentials=flask.session['credentials']# Reconstruct the credentials object.credentials=google.oauth2.credentials.Credentials(refresh_token=session_credentials.get('refresh_token'),scopes=session_credentials.get('granted_scopes'),token=session_credentials.get('token'),client_id=client_config.get('client_id'),client_secret=client_config.get('client_secret'),token_uri=client_config.get('token_uri'))revoke=requests.post('https://oauth2.googleapis.com/revoke',params={'token':credentials.token},headers={'content-type':'application/x-www-form-urlencoded'})status_code=getattr(revoke,'status_code')ifstatus_code==200:# Clear the user's session credentials after successful revocationif'credentials'inflask.session:delflask.session['credentials']delflask.session['features']return('Credentials successfully revoked.'+print_index_table())else:return('An error occurred.'+print_index_table())@app.route('/clear')defclear_credentials():if'credentials'inflask.session:delflask.session['credentials']return('Credentials have been cleared.<br><br>'+print_index_table())defcredentials_to_dict(credentials):return{'token':credentials.token,'refresh_token':credentials.refresh_token,'granted_scopes':credentials.granted_scopes}defcheck_granted_scopes(credentials):features={}if'https://www.googleapis.com/auth/drive.metadata.readonly'incredentials['granted_scopes']:features['drive']=Trueelse:features['drive']=Falseif'https://www.googleapis.com/auth/calendar.readonly'incredentials['granted_scopes']:features['calendar']=Trueelse:features['calendar']=Falsereturnfeaturesdefprint_index_table():return('<table>'+'<tr><td><a href="/authorize">Test the auth flow directly</a></td>'+'<td>Go directly to the authorization flow. If there are stored '+' credentials, you still might not be prompted to reauthorize '+' the application.</td></tr>'+'<tr><td><a href="/drive">Call Drive API directly</a></td>'+'<td> Use stored credentials to call the API, you still might not be prompted to reauthorize '+' the application.</td></tr>'+'<tr><td><a href="/calendar">Call Calendar API directly</a></td>'+'<td> Use stored credentials to call the API, you still might not be prompted to reauthorize '+' the application.</td></tr>'+'<tr><td><a href="/revoke">Revoke current credentials</a></td>'+'<td>Revoke the access token associated with the current user '+' session. After revoking credentials, if you go to the test '+' page, you should see an <code>invalid_grant</code> error.'+'</td></tr>'+'<tr><td><a href="/clear">Clear Flask session credentials</a></td>'+'<td>Clear the access token currently stored in the user session. '+' After clearing the token, if you <a href="/authorize">authorize</a> '+' again, you should go back to the auth flow.'+'</td></tr></table>')if__name__=='__main__':# When running locally, disable OAuthlib's HTTPs verification.# ACTION ITEM for developers:# When running in production *do not* leave this option enabled.os.environ['OAUTHLIB_INSECURE_TRANSPORT']='1'# This disables the requested scopes and granted scopes check.# If users only grant partial request, the warning would not be thrown.os.environ['OAUTHLIB_RELAX_TOKEN_SCOPE']='1'# Specify a hostname and port that are set as a valid redirect URI# for your API project in the Google API Console.app.run('localhost',8080,debug=True)
require'googleauth'require'googleauth/web_user_authorizer'require'googleauth/stores/redis_token_store'require'google/apis/drive_v3'require'google/apis/calendar_v3'require'sinatra'configuredoenable:sessions# Required, call the from_file method to retrieve the client ID from a# client_secret.json file.set:client_id,Google::Auth::ClientId.from_file('/path/to/client_secret.json')# Required, scope value# Access scopes for two non-Sign-In scopes: Read-only Drive activity and Google Calendar.scope=['Google::Apis::DriveV3::AUTH_DRIVE_METADATA_READONLY','Google::Apis::CalendarV3::AUTH_CALENDAR_READONLY']# Required, Authorizers require a storage instance to manage long term persistence of# access and refresh tokens.set:token_store,Google::Auth::Stores::RedisTokenStore.new(redis:Redis.new)# Required, indicate where the API server will redirect the user after the user completes# the authorization flow. The redirect URI is required. The value must exactly# match one of the authorized redirect URIs for the OAuth 2.0 client, which you# configured in the API Console. If this value doesn't match an authorized URI,# you will get a 'redirect_uri_mismatch' error.set:callback_uri,'/oauth2callback'# To use OAuth2 authentication, we need access to a CLIENT_ID, CLIENT_SECRET, AND REDIRECT_URI# from the client_secret.json file. To get these credentials for your application, visit# https://console.cloud.google.com/apis/credentials.set:authorizer,Google::Auth::WebUserAuthorizer.new(settings.client_id,settings.scope,settings.token_store,callback_uri:settings.callback_uri)endget'/'do# NOTE: Assumes the user is already authenticated to the appuser_id=request.session['user_id']# Fetch stored credentials for the user from the given request session.# nil if none presentcredentials=settings.authorizer.get_credentials(user_id,request)ifcredentials.nil?# Generate a url that asks the user to authorize requested scope(s).# Then, redirect user to the url.redirectsettings.authorizer.get_authorization_url(request:request)end# User authorized the request. Now, check which scopes were granted.ifcredentials.scope.include?(Google::Apis::DriveV3::AUTH_DRIVE_METADATA_READONLY)# User authorized read-only Drive activity permission.# Example of using Google Drive API to list filenames in user's Drive.drive=Google::Apis::DriveV3::DriveService.newfiles=drive.list_files(options:{authorization:credentials})"<pre>#{JSON.pretty_generate(files.to_h)}</pre>"else# User didn't authorize read-only Drive activity permission.# Update UX and application accordinglyend# Check if user authorized Calendar read permission.ifcredentials.scope.include?(Google::Apis::CalendarV3::AUTH_CALENDAR_READONLY)# User authorized Calendar read permission.# Calling the APIs, etc.else# User didn't authorize Calendar read permission.# Update UX and application accordinglyendend# Receive the callback from Google's OAuth 2.0 server.get'/oauth2callback'do# Handle the result of the oauth callback. Defers the exchange of the code by# temporarily stashing the results in the user's session.target_url=Google::Auth::WebUserAuthorizer.handle_auth_callback_deferred(request)redirecttarget_urlend
نود جی اس
To run this example:
در API Console, add the URL of the local machine to the list of redirect URLs. For example, add http://localhost .
Make sure you have maintenance LTS, active LTS, or current release of Node.js installed.
Create a new directory and change to it. For example:
mkdir ~/nodejs-oauth2-example
cd ~/nodejs-oauth2-example
Create the files main.js with the following content.
Run the example:
node .\main.js
main.js
consthttp=require('http');consthttps=require('https');consturl=require('url');const{google}=require('googleapis');constcrypto=require('crypto');constexpress=require('express');constsession=require('express-session');/** * To use OAuth2 authentication, we need access to a CLIENT_ID, CLIENT_SECRET, AND REDIRECT_URI. * To get these credentials for your application, visit * https://console.cloud.google.com/apis/credentials. */constoauth2Client=newgoogle.auth.OAuth2(YOUR_CLIENT_ID,YOUR_CLIENT_SECRET,YOUR_REDIRECT_URL);// Access scopes for two non-Sign-In scopes: Read-only Drive activity and Google Calendar.constscopes=['https://www.googleapis.com/auth/drive.metadata.readonly','https://www.googleapis.com/auth/calendar.readonly'];/* Global variable that stores user credential in this code example. * ACTION ITEM for developers: * Store user's refresh token in your data store if * incorporating this code into your real app. * For more information on handling refresh tokens, * see https://github.com/googleapis/google-api-nodejs-client#handling-refresh-tokens */letuserCredential=null;asyncfunctionmain(){constapp=express();app.use(session({secret:'your_secure_secret_key',// Replace with a strong secretresave:false,saveUninitialized:false,}));// Example on redirecting user to Google's OAuth 2.0 server.app.get('/',async(req,res)=>{// Generate a secure random state value.conststate=crypto.randomBytes(32).toString('hex');// Store state in the sessionreq.session.state=state;// Generate a url that asks permissions for the Drive activity and Google Calendar scopeconstauthorizationUrl=oauth2Client.generateAuthUrl({// 'online' (default) or 'offline' (gets refresh_token)access_type:'offline',/** Pass in the scopes array defined above. * Alternatively, if only one scope is needed, you can pass a scope URL as a string */scope:scopes,// Enable incremental authorization. Recommended as a best practice.include_granted_scopes:true,// Include the state parameter to reduce the risk of CSRF attacks.state:state});res.redirect(authorizationUrl);});// Receive the callback from Google's OAuth 2.0 server.app.get('/oauth2callback',async(req,res)=>{// Handle the OAuth 2.0 server responseletq=url.parse(req.url,true).query;if(q.error){// An error response e.g. error=access_deniedconsole.log('Error:'+q.error);}elseif(q.state!==req.session.state){//check state valueconsole.log('State mismatch. Possible CSRF attack');res.end('State mismatch. Possible CSRF attack');}else{// Get access and refresh tokens (if access_type is offline)let{tokens}=awaitoauth2Client.getToken(q.code);oauth2Client.setCredentials(tokens);/** Save credential to the global variable in case access token was refreshed. * ACTION ITEM: In a production app, you likely want to save the refresh token * in a secure persistent database instead. */userCredential=tokens;// User authorized the request. Now, check which scopes were granted.if(tokens.scope.includes('https://www.googleapis.com/auth/drive.metadata.readonly')){// User authorized read-only Drive activity permission.// Example of using Google Drive API to list filenames in user's Drive.constdrive=google.drive('v3');drive.files.list({auth:oauth2Client,pageSize:10,fields:'nextPageToken, files(id, name)',},(err1,res1)=>{if(err1)returnconsole.log('The API returned an error: '+err1);constfiles=res1.data.files;if(files.length){console.log('Files:');files.map((file)=>{console.log(`${file.name} (${file.id})`);});}else{console.log('No files found.');}});}else{// User didn't authorize read-only Drive activity permission.// Update UX and application accordingly}// Check if user authorized Calendar read permission.if(tokens.scope.includes('https://www.googleapis.com/auth/calendar.readonly')){// User authorized Calendar read permission.// Calling the APIs, etc.}else{// User didn't authorize Calendar read permission.// Update UX and application accordingly}}});// Example on revoking a tokenapp.get('/revoke',async(req,res)=>{// Build the string for the POST requestletpostData="token="+userCredential.access_token;// Options for POST request to Google's OAuth 2.0 server to revoke a tokenletpostOptions={host:'oauth2.googleapis.com',port:'443',path:'/revoke',method:'POST',headers:{'Content-Type':'application/x-www-form-urlencoded','Content-Length':Buffer.byteLength(postData)}};// Set up the requestconstpostReq=https.request(postOptions,function(res){res.setEncoding('utf8');res.on('data',d=>{console.log('Response: '+d);});});postReq.on('error',error=>{console.log(error)});// Post the request with datapostReq.write(postData);postReq.end();});constserver=http.createServer(app);server.listen(8080);}main().catch(console.error);
HTTP/REST
This Python example uses the Flask framework and the Requests library to demonstrate the OAuth 2.0 web flow. We recommend using the Google API Client Library for Python for this flow. (The example in the Python tab does use the client library.)
importjsonimportflaskimportrequestsapp=flask.Flask(__name__)# To get these credentials (CLIENT_ID CLIENT_SECRET) and for your application, visit# https://console.cloud.google.com/apis/credentials.CLIENT_ID='123456789.apps.googleusercontent.com'CLIENT_SECRET='abc123'# Read from a file or environmental variable in a real app# Access scopes for two non-Sign-In scopes: Read-only Drive activity and Google Calendar.SCOPE='https://www.googleapis.com/auth/drive.metadata.readonly https://www.googleapis.com/auth/calendar.readonly'# Indicate where the API server will redirect the user after the user completes# the authorization flow. The redirect URI is required. The value must exactly# match one of the authorized redirect URIs for the OAuth 2.0 client, which you# configured in the API Console. If this value doesn't match an authorized URI,# you will get a 'redirect_uri_mismatch' error.REDIRECT_URI='http://example.com/oauth2callback'@app.route('/')defindex():if'credentials'notinflask.session:returnflask.redirect(flask.url_for('oauth2callback'))credentials=json.loads(flask.session['credentials'])ifcredentials['expires_in'] <=0:returnflask.redirect(flask.url_for('oauth2callback'))else:# User authorized the request. Now, check which scopes were granted.if'https://www.googleapis.com/auth/drive.metadata.readonly'incredentials['scope']:# User authorized read-only Drive activity permission.# Example of using Google Drive API to list filenames in user's Drive.headers={'Authorization':'Bearer {}'.format(credentials['access_token'])}req_uri='https://www.googleapis.com/drive/v2/files'r=requests.get(req_uri,headers=headers).textelse:# User didn't authorize read-only Drive activity permission.# Update UX and application accordinglyr='User did not authorize Drive permission.'# Check if user authorized Calendar read permission.if'https://www.googleapis.com/auth/calendar.readonly'incredentials['scope']:# User authorized Calendar read permission.# Calling the APIs, etc.r+='User authorized Calendar permission.'else:# User didn't authorize Calendar read permission.# Update UX and application accordinglyr+='User did not authorize Calendar permission.'returnr@app.route('/oauth2callback')defoauth2callback():if'code'notinflask.request.args:state=str(uuid.uuid4())flask.session['state']=state# Generate a url that asks permissions for the Drive activity# and Google Calendar scope. Then, redirect user to the url.auth_uri=('https://accounts.google.com/o/oauth2/v2/auth?response_type=code''&client_id={}&redirect_uri={}&scope={}&state={}').format(CLIENT_ID,REDIRECT_URI,SCOPE,state)returnflask.redirect(auth_uri)else:if'state'notinflask.request.argsorflask.request.args['state']!=flask.session['state']:return'State mismatch. Possible CSRF attack.',400auth_code=flask.request.args.get('code')data={'code':auth_code,'client_id':CLIENT_ID,'client_secret':CLIENT_SECRET,'redirect_uri':REDIRECT_URI,'grant_type':'authorization_code'}# Exchange authorization code for access and refresh tokens (if access_type is offline)r=requests.post('https://oauth2.googleapis.com/token',data=data)flask.session['credentials']=r.textreturnflask.redirect(flask.url_for('index'))if__name__=='__main__':importuuidapp.secret_key=str(uuid.uuid4())app.debug=Falseapp.run()
Redirect URI validation rules
Google applies the following validation rules to redirect URIs in order to help developers keep their applications secure. Your redirect URIs must adhere to these rules. See RFC 3986 section 3 for the definition of domain, host, path, query, scheme and userinfo, mentioned below.
Redirect URIs cannot contain URL shortener domains (eg goo.gl ) unless the app owns the domain. Furthermore, if an app that owns a shortener domain chooses to redirect to that domain, that redirect URI must either contain “/google-callback/” in its path or end with “/google-callback” .
In the OAuth 2.0 protocol, your app requests authorization to access resources, which are identified by scopes. It is considered a best user-experience practice to request authorization for resources at the time you need them. To enable that practice, Google's authorization server supports incremental authorization. This feature lets you request scopes as they are needed and, if the user grants permission for the new scope, returns an authorization code that may be exchanged for a token containing all scopes the user has granted the project.
For example, an app that lets people sample music tracks and create mixes might need very few resources at sign-in time, perhaps nothing more than the name of the person signing in. However, saving a completed mix would require access to their Google Drive. Most people would find it natural if they only were asked for access to their Google Drive at the time the app actually needed it.
In this case, at sign-in time the app might request the openid and profile scopes to perform basic sign-in, and then later request the https://www.googleapis.com/auth/drive.file scope at the time of the first request to save a mix.
To implement incremental authorization, you complete the normal flow for requesting an access token but make sure that the authorization request includes previously granted scopes. This approach allows your app to avoid having to manage multiple access tokens.
The following rules apply to an access token obtained from an incremental authorization:
The token can be used to access resources corresponding to any of the scopes rolled into the new, combined authorization.
When you use the refresh token for the combined authorization to obtain an access token, the access token represents the combined authorization and can be used for any of the scope values included in the response.
The combined authorization includes all scopes that the user granted to the API project even if the grants were requested from different clients. For example, if a user granted access to one scope using an application's desktop client and then granted another scope to the same application via a mobile client, the combined authorization would include both scopes.
If you revoke a token that represents a combined authorization, access to all of that authorization's scopes on behalf of the associated user are revoked simultaneously.
In Python, set the include_granted_scopes keyword argument to true to ensure that an authorization request includes previously granted scopes. It is very possible that include_granted_scopes will not be the only keyword argument that you set, as shown in the example below.
authorization_url,state=flow.authorization_url(# Enable offline access so that you can refresh an access token without# re-prompting the user for permission. Recommended for web server apps.access_type='offline',# Enable incremental authorization. Recommended as a best practice.include_granted_scopes='true')
constauthorizationUrl=oauth2Client.generateAuthUrl({// 'online' (default) or 'offline' (gets refresh_token)access_type:'offline',/** Pass in the scopes array defined above. * Alternatively, if only one scope is needed, you can pass a scope URL as a string */scope:scopes,// Enable incremental authorization. Recommended as a best practice.include_granted_scopes:true});
HTTP/REST
GET https://accounts.google.com/o/oauth2/v2/auth?
client_id=your_client_id&
response_type=code&
state=state_parameter_passthrough_value&
scope=https%3A//www.googleapis.com/auth/drive.metadata.readonly%20https%3A//www.googleapis.com/auth/calendar.readonly&
redirect_uri=https%3A//developers.google.com/oauthplayground&
prompt=consent&
include_granted_scopes=true
Refreshing an access token (offline access)
Access tokens periodically expire and become invalid credentials for a related API request. You can refresh an access token without prompting the user for permission (including when the user is not present) if you requested offline access to the scopes associated with the token.
If you use a Google API Client Library, the client object refreshes the access token as needed as long as you configure that object for offline access.
If you are not using a client library, you need to set the access_type HTTP query parameter to offline when redirecting the user to Google's OAuth 2.0 server . In that case, Google's authorization server returns a refresh token when you exchange an authorization code for an access token. Then, if the access token expires (or at any other time), you can use a refresh token to obtain a new access token.
Requesting offline access is a requirement for any application that needs to access a Google API when the user is not present. For example, an app that performs backup services or executes actions at predetermined times needs to be able to refresh its access token when the user is not present. The default style of access is called online .
Server-side web applications, installed applications, and devices all obtain refresh tokens during the authorization process. Refresh tokens are not typically used in client-side (JavaScript) web applications.
پی اچ پی
If your application needs offline access to a Google API, set the API client's access type to offline :
$client->setAccessType("offline");
After a user grants offline access to the requested scopes, you can continue to use the API client to access Google APIs on the user's behalf when the user is offline. The client object will refresh the access token as needed.
پایتون
In Python, set the access_type keyword argument to offline to ensure that you will be able to refresh the access token without having to re-prompt the user for permission. It is very possible that access_type will not be the only keyword argument that you set, as shown in the example below.
authorization_url,state=flow.authorization_url(# Enable offline access so that you can refresh an access token without# re-prompting the user for permission. Recommended for web server apps.access_type='offline',# Enable incremental authorization. Recommended as a best practice.include_granted_scopes='true')
After a user grants offline access to the requested scopes, you can continue to use the API client to access Google APIs on the user's behalf when the user is offline. The client object will refresh the access token as needed.
روبی
If your application needs offline access to a Google API, set the API client's access type to offline :
After a user grants offline access to the requested scopes, you can continue to use the API client to access Google APIs on the user's behalf when the user is offline. The client object will refresh the access token as needed.
نود جی اس
If your application needs offline access to a Google API, set the API client's access type to offline :
constauthorizationUrl=oauth2Client.generateAuthUrl({// 'online' (default) or 'offline' (gets refresh_token)access_type:'offline',/** Pass in the scopes array defined above. * Alternatively, if only one scope is needed, you can pass a scope URL as a string */scope:scopes,// Enable incremental authorization. Recommended as a best practice.include_granted_scopes:true});
After a user grants offline access to the requested scopes, you can continue to use the API client to access Google APIs on the user's behalf when the user is offline. The client object will refresh the access token as needed.
Access tokens expire. This library will automatically use a refresh token to obtain a new access token if it is about to expire. An easy way to make sure you always store the most recent tokens is to use the tokens event:
oauth2Client.on('tokens',(tokens)=>{if(tokens.refresh_token){// store the refresh_token in your secure persistent databaseconsole.log(tokens.refresh_token);}console.log(tokens.access_token);});
This tokens event only occurs in the first authorization, and you need to have set your access_type to offline when calling the generateAuthUrl method to receive the refresh token. If you have already given your app the requisiste permissions without setting the appropriate constraints for receiving a refresh token, you will need to re-authorize the application to receive a fresh refresh token.
To set the refresh_token at a later time, you can use the setCredentials method:
Once the client has a refresh token, access tokens will be acquired and refreshed automatically in the next call to the API.
HTTP/REST
To refresh an access token, your application sends an HTTPS POST request to Google's authorization server ( https://oauth2.googleapis.com/token ) that includes the following parameters:
The refresh token returned from the authorization code exchange.
The following snippet shows a sample request:
POST /token HTTP/1.1
Host: oauth2.googleapis.com
Content-Type: application/x-www-form-urlencoded
client_id=your_client_id&
refresh_token=refresh_token&
grant_type=refresh_token
As long as the user has not revoked the access granted to the application, the token server returns a JSON object that contains a new access token. The following snippet shows a sample response:
Note that there are limits on the number of refresh tokens that will be issued; one limit per client/user combination, and another per user across all clients. You should save refresh tokens in long-term storage and continue to use them as long as they remain valid. If your application requests too many refresh tokens, it may run into these limits, in which case older refresh tokens will stop working.
It is also possible for an application to programmatically revoke the access given to it. Programmatic revocation is important in instances where a user unsubscribes, removes an application, or the API resources required by an app have significantly changed. In other words, part of the removal process can include an API request to ensure the permissions previously granted to the application are removed.
پی اچ پی
To programmatically revoke a token, call revokeToken() :
$client->revokeToken();
پایتون
To programmatically revoke a token, make a request to https://oauth2.googleapis.com/revoke that includes the token as a parameter and sets the Content-Type header:
The token can be an access token or a refresh token. If the token is an access token and it has a corresponding refresh token, the refresh token will also be revoked.
If the revocation is successfully processed, then the status code of the response is 200 . For error conditions, a status code 400 is returned along with an error code.
نود جی اس
To programmatically revoke a token, make an HTTPS POST request to /revoke endpoint:
consthttps=require('https');// Build the string for the POST requestletpostData="token="+userCredential.access_token;// Options for POST request to Google's OAuth 2.0 server to revoke a tokenletpostOptions={host:'oauth2.googleapis.com',port:'443',path:'/revoke',method:'POST',headers:{'Content-Type':'application/x-www-form-urlencoded','Content-Length':Buffer.byteLength(postData)}};// Set up the requestconstpostReq=https.request(postOptions,function(res){res.setEncoding('utf8');res.on('data',d=>{console.log('Response: '+d);});});postReq.on('error',error=>{console.log(error)});// Post the request with datapostReq.write(postData);postReq.end();
The token parameter can be an access token or a refresh token. If the token is an access token and it has a corresponding refresh token, the refresh token will also be revoked.
If the revocation is successfully processed, then the status code of the response is 200 . For error conditions, a status code 400 is returned along with an error code.
HTTP/REST
To programmatically revoke a token, your application makes a request to https://oauth2.googleapis.com/revoke and includes the token as a parameter:
The token can be an access token or a refresh token. If the token is an access token and it has a corresponding refresh token, the refresh token will also be revoked.
If the revocation is successfully processed, then the HTTP status code of the response is 200 . For error conditions, an HTTP status code 400 is returned along with an error code.
Time-based access
Time-based access allows a user to grant your app access to their data for a limited duration to complete an action. Time-based access is available in select Google products during the consent flow, giving users the option to grant access for a limited period of time. An example is the Data Portability API which enables a one-time transfer of data.
When a user grants your application time-based access, the refresh token will expire after the specified duration. Note that refresh tokens may be invalidated earlier under specific circumstances; see these cases for details. The refresh_token_expires_in field returned in the authorization code exchange response represents the time remaining until the refresh token expires in such cases.
Implementing Cross-Account Protection
An additional step you should take to protect your users' accounts is implementing Cross-Account Protection by utilizing Google's Cross-Account Protection Service. This service lets you subscribe to security event notifications which provide information to your application about major changes to the user account. You can then use the information to take action depending on how you decide to respond to events.
Some examples of the event types sent to your app by Google's Cross-Account Protection Service are:
تاریخ آخرین بهروزرسانی 2025-12-19 بهوقت ساعت هماهنگ جهانی.
[[["درک آسان","easyToUnderstand","thumb-up"],["مشکلم را برطرف کرد","solvedMyProblem","thumb-up"],["غیره","otherUp","thumb-up"]],[["اطلاعاتی که نیاز دارم وجود ندارد","missingTheInformationINeed","thumb-down"],["بیشازحد پیچیده/ مراحل بسیار زیاد","tooComplicatedTooManySteps","thumb-down"],["قدیمی","outOfDate","thumb-down"],["مشکل ترجمه","translationIssue","thumb-down"],["مشکل کد / نمونهها","samplesCodeIssue","thumb-down"],["غیره","otherDown","thumb-down"]],["تاریخ آخرین بهروزرسانی 2025-12-19 بهوقت ساعت هماهنگ جهانی."],[],[]]