[Python] How to obtain familysearch.com token without entering login and password

Discussão em 'Python' iniciado por Stack, Agosto 6, 2025.

  1. Stack

    Stack Membro Participativo

    I am using the following code to obtain FamilySearch API token (according to the documentation https://developers.familysearch.org/main/docs/authentication )

    During authentication I have to manually enter login and password on the familysearch page, the the site redirects me to page with token (my redirect URL)

    The code is working fine. But Is it possible to obtain the token without manually entering login and password?

    from fastapi import FastAPI, Request
    from fastapi.responses import RedirectResponse, HTMLResponse
    from urllib.parse import urlencode
    import requests

    CLIENT_ID = 'MY_ID'
    REDIRECT_URI = 'MY_URL'
    AUTH_URL = 'https://identbeta.familysearch.org/cis-web/oauth2/v3/authorization'
    TOKEN_URL = 'https://identbeta.familysearch.org/cis-web/oauth2/v3/token'

    app = FastAPI()

    @app.get("/authorize")
    def authorize():
    params = {
    'response_type': 'code',
    'client_id': CLIENT_ID,
    'redirect_uri': REDIRECT_URI,
    'scope': 'openid profile email',
    'state': 'random_state_string',
    'realm': '/wales' # Add realm parameter for FamilySearch
    }
    url = f"{AUTH_URL}?{urlencode(params)}"
    return RedirectResponse(url)

    @app.get("/oauth2/callback")
    async def oauth_callback(code: str = None, error: str = None, state: str = None):
    if error:
    return HTMLResponse(f"""
    <html>
    <body>
    <h1>OAuth Error</h1>
    <p>Error: {error}</p>
    <p>State: {state}</p>
    <a href="/authorize">Try Again</a>
    </body>
    </html>
    """)

    if not code:
    return HTMLResponse("No authorization code received")

    # Exchange authorization code for access token
    token_data = {
    'grant_type': 'authorization_code',
    'client_id': CLIENT_ID,
    'redirect_uri': REDIRECT_URI,
    'code': code
    }

    if CLIENT_SECRET:
    token_data['client_secret'] = CLIENT_SECRET

    try:
    response = requests.post(TOKEN_URL, data=token_data)
    response.raise_for_status()
    token_info = response.json()

    return HTMLResponse(f"""
    <html>
    <body>
    <h1>OAuth Success!</h1>
    <p>Authorization code: {code}</p>
    <p>Access token: {token_info.get('access_token', 'Not provided')}</p>
    <p>Token type: {token_info.get('token_type', 'Not provided')}</p>
    <p>Expires in: {token_info.get('expires_in', 'Not provided')}</p>
    <a href="/authorize">Authorize Again</a>
    </body>
    </html>
    """)

    except requests.exceptions.RequestException as e:
    return HTMLResponse(f"""
    <html>
    <body>
    <h1>Token Exchange Error</h1>
    <p>Error: {str(e)}</p>
    <a href="/authorize">Try Again</a>
    </body>
    </html>
    """)

    @app.get("/")
    def root():
    return {"message": "FamilySearch OAuth2 API", "endpoints": ["/authorize", "/oauth2/callback"]}

    if __name__ == "__main__":
    import uvicorn
    uvicorn.run("main:app", host="0.0.0.0", port=80, reload=True)

    Continue reading...

Compartilhe esta Página