OAuth 2.0 — это про делегированный доступ. Стороннее приложение хочет что-то сделать от имени пользователя, но получать его логин и пароль ему не положено. Вместо этого оно работает с access token — временным ключом, с которым можно ходить к API и выполнять строго ограничённый набор действий.
Смысл в том, что пользователь даёт разрешение, провайдер подтверждает это и выдаёт токен. Пароль при этом вообще никуда не уходит, остаётся у исходного сервиса. Риски утечки учётки уменьшаются, а управление правами становится намного гибче.
Как OAuth 2.0 выглядит в жизни (очень упрощённо) #
- Пользователь жмёт «Войти через <Google/Facebook/GitHub>» в стороннем приложении.
- OAuth-сервер (тот же Google) показывает пользователю экран с запросом прав и просит подтвердить доступ.
- После согласия приложение получает authorization code.
- Этот код приложение обменивает на access token (иногда ещё и на refresh token).
- Дальше приложение ходит к защищённым API с этим токеном, представляясь пользователем.
Access token живёт ограниченное время и может быть отозван в любой момент. Если выдали refresh token, можно молча получить новый access token без повторного логина пользователя.
Где обычно применяют OAuth 2.0 #
- Логин через крупных провайдеров: Google, Facebook, GitHub и т.д.;
- Доступ к сторонним API от имени пользователя — календарь, хранилища, почта;
- Мобильные и SPA-приложения, где хранить пароли просто небезопасно и неудобно;
- Микросервисы, которые авторизуют запросы друг к другу по токенам;
- Интеграции SaaS-сервисов, где между собой обмениваются не логинами, а токенами.
Чем хорош OAuth 2.0 #
- Безопасностью — приложения не видят пользовательских паролей вообще;
- Гибкостью — доступ можно резать по scope: дать, например, только чтение профиля, без права писать;
- Контролем — пользователь (или админ) может в любой момент забрать права у конкретного приложения;
- Совместимостью — почти все крупные платформы и API уже умеют работать по этому протоколу.
Пример из повседневности #
Когда вы заходите в Trello или Slack «через Google», на самом деле срабатывает OAuth 2.0. Google не отдаёт этим сервисам ваш пароль, он просто подтверждает, что вы — это вы, и выдаёт приложению токен, с которым оно уже работает.
Сейчас OAuth 2.0 — один из базовых кирпичей безопасности для веба, мобильных приложений и API-интеграций. Он позволяет упростить аутентификацию и при этом нормально защитить пользовательские данные.
1. OAuth 2.0 через Ingress Controller в Kubernetes (oauth2-proxy + NGINX) #
Helm-значения для oauth2-proxy (пример с Google) #
# values.yaml
config:
clientID: "<GOOGLE_CLIENT_ID>"
clientSecret: "<GOOGLE_CLIENT_SECRET>"
cookieSecret: "<RANDOM_32BYTE_BASE64>"
provider: google
emailDomains:
- "*"
upstreams:
- "file:///dev/null"
redirectURL: "https://app.example.com/oauth2/callback"
extraArgs:
whitelist-domain: ".example.com"
Ingress с проверкой через oauth2-proxy #
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app-ingress
annotations:
nginx.ingress.kubernetes.io/auth-url: "https://oauth2-proxy.example.com/oauth2/auth"
nginx.ingress.kubernetes.io/auth-signin: "https://oauth2-proxy.example.com/oauth2/start?rd=$request_uri"
spec:
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: app-service
port:
number: 80
Пока пользователь не пройдёт авторизацию через OAuth-провайдера, до самого приложения его просто не пустят — NGINX завернёт запрос на oauth2-proxy.
2. GitHub OAuth App: базовая настройка #
В интерфейсе настроек GitHub создаётся новая OAuth App, и там заполняются основные поля:
- Application name: что-то вроде «MyApp GitHub Login»;
- Homepage URL:
https://myapp.example.com; - Authorization callback URL:
https://myapp.example.com/oauth/callback.
На выходе у вас появляются Client ID и Client Secret. Эти значения вы уже пробрасываете в своё приложение, middleware или прокси, которое будет работать по OAuth.
3. CI/CD: использование OAuth-токена в GitHub Actions #
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Exchange OAuth code for access token
run: |
TOKEN=$(curl -X POST
-d "client_id=${{ secrets.GH_CLIENT_ID }}"
-d "client_secret=${{ secrets.GH_CLIENT_SECRET }}"
-d "code=${{ secrets.GH_AUTH_CODE }}"
https://github.com/login/oauth/access_token
| grep access_token | cut -d= -f2 | cut -d& -f1)
echo "OAUTH_TOKEN=$TOKEN" >> $GITHUB_ENV
- name: Use token
run: curl -H "Authorization: token $OAUTH_TOKEN" https://api.github.com/user
Такой шаг пригодится, если нужно что-то делать от имени конкретного пользователя GitHub: проверять его данные, создавать pull request, ходить в API с его правами и т.д.
