ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 02.01.2026

Просмотров: 2763

Скачиваний: 0

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

15. SESSIONS

1

2

3

4

5

6

7

8

9

>>>request.session.flash(’info message’)

>>>request.session.peek_flash()

[’info message’]

>>>request.session.peek_flash() [’info message’]

>>>request.session.pop_flash() [’info message’]

>>>request.session.peek_flash()

[]

15.6 Preventing Cross-Site Request Forgery Attacks

Cross-site request forgery attacks are a phenomenon whereby a user with an identity on your website might click on a URL or button on another website which secretly redirects the user to your application to perform some command that requires elevated privileges.

You can avoid most of these attacks by making sure that the correct CSRF token has been set in an Pyramid session object before performing any actions in code which requires elevated privileges that is invoked via a form post. To use CSRF token support, you must enable a session factory as described in Using The Default Session Factory or Using Alternate Session Factories.

15.6.1 Using the session.get_csrf_token Method

To get the current CSRF token from the session, use the session.get_csrf_token() method.

token = request.session.get_csrf_token()

The session.get_csrf_token() method accepts no arguments. It returns a CSRF token string. If session.get_csrf_token() or session.new_csrf_token() was invoked previously for this session, the existing token will be returned. If no CSRF token previously existed for this session, a new token will be will be set into the session and returned. The newly created token will be opaque and randomized.

You can use the returned token as the value of a hidden field in a form that posts to a method that requires elevated privileges. The handler for the form post should use session.get_csrf_token() again to obtain the current CSRF token related to the user from the session, and compare it to the value of the hidden form field. For example, if your form rendering included the CSRF token obtained via session.get_csrf_token() as a hidden input field named csrf_token:

176

15.6. PREVENTING CROSS-SITE REQUEST FORGERY ATTACKS

1

2

3

token = request.session.get_csrf_token() if token != request.POST[’csrf_token’]:

raise ValueError(’CSRF token did not match’)

15.6.2 Using the session.new_csrf_token Method

To explicitly add a new CSRF token to the session, use the session.new_csrf_token() method. This differs only from session.get_csrf_token() inasmuch as it clears any existing CSRF token, creates a new CSRF token, sets the token into the session, and returns the token.

token = request.session.new_csrf_token()

177


15. SESSIONS

178


CHAPTER

SIXTEEN

USING EVENTS

An event is an object broadcast by the Pyramid framework at interesting points during the lifetime of an application. You don’t need to use events in order to create most Pyramid applications, but they can be useful when you want to perform slightly advanced operations. For example, subscribing to an event can allow you to run some code as the result of every new request.

Events in Pyramid are always broadcast by the framework. However, they only become useful when you register a subscriber. A subscriber is a function that accepts a single argument named event:

1

2

def mysubscriber(event): print event

The above is a subscriber that simply prints the event to the console when it’s called.

The

mere

existence

of

a subscriber

function, however,

is not

sufficient to

arrange

for

it to

be

called.

To

arrange for

the subscriber to be

called,

you’ll need

to use

the

pyramid.config.Configurator.add_subscriber() method or you’ll need to use the pyramid.events.subscriber() decorator to decorate a function found via a scan.

16.1 Configuring an Event Listener Imperatively

You can imperatively configure a subscriber function to be called for some event type via the add_subscriber() method (see also Configurator):

179

16. USING EVENTS

1

from pyramid.events import NewRequest

2

 

3

from subscribers import mysubscriber

4

 

5

# "config" below is assumed to be an instance of a

6

# pyramid.config.Configurator object

7

 

8

config.add_subscriber(mysubscriber, NewRequest)

 

 

The first argument to add_subscriber() is the subscriber function (or a dotted Python name which refers to a subscriber callable); the second argument is the event type.

16.2 Configuring an Event Listener Using a Decorator

You can configure a subscriber function to be called for some event type via the pyramid.events.subscriber() function.

1

2

3

4

5

6

from pyramid.events import NewRequest from pyramid.events import subscriber

@subscriber(NewRequest) def mysubscriber(event):

event.request.foo = 1

When the subscriber() decorator is used a scan must be performed against the package containing the decorated function for the decorator to have any effect.

Either of the above registration examples implies that every time the Pyramid framework emits an event object that supplies an pyramid.events.NewRequest interface, the mysubscriber function will be called with an event object.

As you can see, a subscription is made in terms of a class (such as pyramid.events.NewResponse). The event object sent to a subscriber will always be an object that possesses an interface. For pyramid.events.NewResponse, that interface is pyramid.interfaces.INewResponse. The interface documentation provides information about available attributes and methods of the event objects.

The return value of a subscriber function is ignored. Subscribers to the same event type are not guaranteed to be called in any particular order relative to each other.

All the concrete Pyramid event types are documented in the pyramid.events API documentation.

180


16.3. AN EXAMPLE

16.3 An Example

If you create event listener functions in a subscribers.py file in your application like so:

1 def handle_new_request(event):

2print ’request’, event.request

3

4 def handle_new_response(event):

5print ’response’, event.response

You may configure these functions to be called at the appropriate times by adding the following code to your application’s configuration startup:

1

# config is an instance of pyramid.config.Configurator

2

 

3

config.add_subscriber(’myproject.subscribers.handle_new_request’,

4

’pyramid.events.NewRequest’)

5

config.add_subscriber(’myproject.subscribers.handle_new_response’,

6

’pyramid.events.NewResponse’)

 

 

Either mechanism causes the functions in subscribers.py to be registered as event subscribers. Under this configuration, when the application is run, each time a new request or response is detected, a message will be printed to the console.

Each of our subscriber functions accepts an event object and prints an attribute of the event object. This begs the question: how can we know which attributes a particular event has?

We know that pyramid.events.NewRequest event objects have a request attribute, which is a request object, because the interface defined at pyramid.interfaces.INewRequest says it must. Likewise, we know that pyramid.interfaces.NewResponse events have a response attribute, which is a response object constructed by your application, because the interface defined at pyramid.interfaces.INewResponse says it must (pyramid.events.NewResponse objects also have a request).

181

16. USING EVENTS

182

CHAPTER

SEVENTEEN

ENVIRONMENT VARIABLES AND

.INI FILE SETTINGS

Pyramid behavior can be configured through a combination of operating system environment variables and .ini configuration file application section settings. The meaning of the environment variables and the configuration file settings overlap.

latex-note.png

Where a configuration file setting exists with the same meaning as an environment variable, and both are present at application startup time, the environment variable setting takes precedence.

The term “configuration file setting name” refers to a key in the .ini configuration for your application. The configuration file setting names documented in this chapter are reserved for Pyramid use. You should not use them to indicate application-specific configuration settings.

183