Nikita Grishko, JUNO
«Произвольная строка, которая будет возвращена вместе с результатом авторизации.»
state = get_random_string()
session.set(state, expire=5 * 60)
redirect_url = 'https://oauth.vk.com/authorize?...&state=' + state
...
state = query['state']
if state not in session:
return Response(status=400)
...
$ http https://www.googleapis.com/oauth2/v3/tokeninfo?access_token=1/fFBGRNJru1FQd44AzqT3Zg
...
{
"audience":"8819981768.apps.googleusercontent.com",
"user_id":"123456789",
"scope":"profile email",
"expires_in":436
}
Все должно быть отключаемым
key = '{user_ip}:{sec}'.format(user_ip=user_ip, sec=int(time.time()))
cache.inrc(key, expire=10 * 60)
end = int(time.time()) + 1
start = end - 60 # one minute
keys = [
'{user_ip}:{sec}'.format(user_ip=user_ip, sec=sec)
for sec in range(start, end)
]
attempts = sum(cache.get_many(keys))
if attempts > limit:
...
...
Ненавидишь своего пользователя?
Добавь капчу, пусть он страдает!
принцип защиты систем от злоупотребления услугами, основанный на необходимости выполнения запрашивающей стороной некоторой достаточно сложной длительной работы, результат которой легко и быстро проверяется обслуживающей стороной
stamp = '{ver}:{bits}:{date}:{resource}:{ext}:{rand}:{counter}'.format(**{
'ver': 1,
'bits': 3,
'date': 1457459496,
'resource': 'poffw',
'ext': '',
'rand': 'TI5gjgHjyGYZtbla',
'counter': 12481,
})
prefix = '0' * 3
sha3.sha3_512(stamp).hexdigest().startswith(prefix)
token = random_string()
task = {
'ver': 1,
'bits': 3,
'date': int(time.time()),
'resource': 'poffw',
'ext': '',
'rand': random_string(),
}
await redis.set(token, json.dumps(task))
await redis.expire(token, 60)
$ http 127.0.0.1:8080/login
HTTP/1.1 200 OK
CONTENT-LENGTH: 101
CONTENT-TYPE: application/json; charset=utf-8
DATE: Tue, 08 Mar 2016 18:11:04 GMT
SERVER: Python/3.5 aiohttp/0.21.2
X-POFFW: atIibp2AA2p7xxcW
{
"bits": 1,
"date": 1457460664,
"ext": "",
"rand": "tUJWHkU1x4Hgjosw",
"resource": "poffw",
"ver": 1
}
token = request.headers['X-POFFW']
counter = data['counter']
task = await redis.get(token)
task['counter'] = counter
stamp = '{ver}:{bits}:{date}:{resource}:{ext}:{rand}:{counter}'.format(**task)
prefix = '0' * task['bits']
sha3.sha3_512(stamp).hexdigest().startswith(prefix)
$ http POST 127.0.0.1:8080/login counter=3 'X-POFFW: atIibp2AA2p7xxcW'
HTTP/1.1 200 OK
CONTENT-LENGTH: 0
CONTENT-TYPE: application/json
DATE: Tue, 08 Mar 2016 18:13:50 GMT
SERVER: Python/3.5 aiohttp/0.21.2
var stamp = [task.ver, task.bits, task.date, task.resource,
task.ext, task.rand].join(':'),
prefix = new Array(task.bits + 1).join('0'),
counter = 1,
check = function(counter) {
var hash = CryptoJS.SHA3([stamp, counter].join(':'));
return String(hash, {
outputLength: 512
}).indexOf(prefix) === 0;
};
while (true) {
if (check(counter)) {
return counter;
}
counter += 1;
}
var parallel = new Parallel(task);
parallel.require(pathSHA3).spawn(solveWorker).then(function(counter) {
console.log('Task resolved:', counter);
});