Strategies¶
Different strategies are defined to encapsulate the different frameworks capabilities under a common API to reuse as much code as possible.
Description¶
A strategy’s responsibility is to provide access to:
Request data and host information and URI building
Session access
Project settings
Response types (HTML and redirects)
HTML rendering
Different frameworks implement these features on different ways, thus the need for these interfaces.
Implementing a new Strategy¶
The following methods must be defined on strategies sub-classes.
Request:
def get_request_data(self, merge=True):
"""Return current framework request data (POST or GET)"""
raise NotImplementedError('Implement in subclass')
def request_host(self):
"""Return current host value"""
raise NotImplementedError('Implement in subclass')
def build_absolute_uri(self, path=None):
"""Build absolute URI with given (optional) path"""
raise NotImplementedError('Implement in subclass')
Session:
def session_get(self, name):
"""Return session value for given key"""
raise NotImplementedError('Implement in subclass')
def session_set(self, name, value):
"""Set session value for given key"""
raise NotImplementedError('Implement in subclass')
def session_pop(self, name):
"""Pop session value for given key"""
raise NotImplementedError('Implement in subclass')
get_session_id() and restore_session() have been removed from the
strategy interface. Callbacks must use the initiating browser’s session;
custom backends that used these methods need to migrate to browser-bound
correlation.
Settings:
def get_setting(self, name):
"""Return value for given setting name"""
raise NotImplementedError('Implement in subclass')
Responses:
def html(self, content):
"""Return HTTP response with given content"""
raise NotImplementedError('Implement in subclass')
def redirect(self, url):
"""Return a response redirect to the given URL"""
raise NotImplementedError('Implement in subclass')
def render_html(self, tpl=None, html=None, context=None):
"""Render given template or raw html with given context"""
raise NotImplementedError('Implement in subclass')
BaseStrategy.html_with_headers(content, headers) is a required strategy
hook for returning HTML with the specified HTTP headers. SAML POST callbacks
use it for a protected browser return page. Integrations must implement this
hook using their framework’s response API. A custom strategy without the hook
fails closed during SAML completion. The Django strategy implements it.
Response types¶
Starting with social-auth-core 7, strategies declare their framework response
type through BaseStrategy’s type parameter. The Django integration uses:
from django.http import HttpResponse
from social_core.strategy import BaseStrategy
class DjangoStrategy(BaseStrategy[HttpResponse]):
...
Response-producing hooks such as redirect(), html(), and
html_with_headers() return that type. render_html() still returns a
string. Custom Django strategies inherit the response type from
DjangoStrategy; custom backends can annotate it as
BaseAuth[HttpResponse]. Using BaseStrategy[HttpResponse] at runtime
requires social-auth-core 7 or later.
Pipeline steps decorated with partial or partial_step() may return an
HttpResponse containing a rendered page to pause the pipeline. Annotate
these responses with the framework response type; they do not need a url
attribute. HttpResponseProtocol remains importable for compatibility but
is deprecated.
Effective pipeline request data¶
strategy.request holds the native framework request, when the integration
provides one. It is never replaced by saved partial-pipeline parameters.
strategy.get_request_data(merge=True) reads the current framework request.
With merge=False, it reads the data for the current request method, following
the framework integration’s existing behavior. Custom strategies implement this
hook instead of overriding request_data().
strategy.request_data(merge=True) returns the effective parameters for the
active pipeline. During a partial resume, this includes any confirmed data
replayed from an external validation link. Both values of merge return the
same effective mapping during replay, because saved data no longer has a
separate GET or POST origin. Use get_request_data(), request_get(), or
request_post() when the current framework request is required.
The effective mapping is scoped to execution of the resumed authentication or
disconnect pipeline. The previous mapping is restored when execution completes,
returns a response, or raises an exception. Nested executions restore the outer
mapping. Integration code can establish the same scope with
strategy.pipeline_request_data(data) as a context manager.