Я имею дело со своим уровнем безопасности в проекте Goadesign API.У меня есть некоторые сомнения по поводу того, какую схему безопасности мне использовать.Я постараюсь описать весь мой стек, чтобы вы могли получить лучшее представление: во-первых, мне нужно ввести логин в мой goa api, чтобы пользователь мог просматривать свой профиль на Facebook.Я думаю, что Код авторизации OAuth2 соответствует моим потребностям, поэтому здесь моя реализация пошаговая Код авторизации:
- Статическое js-приложение открывается через кнопку на html-странице Facebook
https://www.facebook.com/v3.2/dialog/oauth?client_id={app-id}&redirect_uri={redirect-uri}&state={state-param}
- Логин пользователя
- Redirect_uri открывает перенаправление обратно в приложение js, которое получает код из параметров.
- Приложение js отправляет запрос, включая код, полученный на шаге 3, в бэкэнд goaна конечную точку
/oauth2/facebook/access_token
, которая выполняет вызов в Facebook для обмена кода на токен.После получения ответа токен и информация о пользователе сохраняются в БД, и токен отправляется обратно в приложение js для будущего вызова.
Пока все хорошо.
ЗдесьСомнения:
- Я определил следующий дизайн
var Oauth2Secure = OAuth2Security("googAuth", func() {
AccessCodeFlow("/authorization", "/oauth2/facebook/access_token")
Scope("my_system:write", "Write to the system")
Scope("my_system:read", "Read anything in there")
})
var _ = Resource("protected_resource", func() {
Description("Is a protected url")
BasePath("/protected_resource")
Security(Oauth2Secure)
Action("list", func() {
Description("List of preotected resource")
Routing(GET("/"))
})
Response(OK)
})
Конечная точка /oauth2/facebook/access_token
- это та, на которую я ссылался в потоке на шаге 4, это имеет смыслно я не понимаю, почему я должен определять конечную точку /authorization
в функции AccessCodeFlow, поскольку это будет конечная точка Facebook.Более того, не имеет смысла выполнять вызов этого /authorization
из бэкэнда, потому что он открывает диалог, с которым пользователь должен взаимодействовать.
Позвонив на мой
/protected_resource
, дал мне этот ответ
{"id":"KyDW0MOn","code":"no_auth_middleware","status":500,"detail":"Auth middleware for security scheme googAuth is not mounted","meta":{"scheme":"googAuth"}}
.Вполне справедливо, что я реализовал промежуточное программное обеспечение, как предложено в примерах безопасности goa
func NewOAuth2Middleware() goa.Middleware {
// Instantiate scheme described in design to retrieve
// Middleware
return func(h goa.Handler) goa.Handler {
return func(ctx context.Context, rw http.ResponseWriter, req *http.Request) error {
token := req.Header["Authorization"]
if token == nil {
return ErrUnauthorized("missing auth header")
}
tok := token[0]
if len(tok) < 9 || !strings.HasPrefix(tok, "Bearer ") {
return ErrUnauthorized("invalid auth header")
}
tok = tok[7:]
// Validate token here against value stored in DB for example
if tok != "valid_token" {
return ErrUnauthorized("invalid token")
}
return h(ctx, rw, req)
}
}
}
Должен ли я действительно использовать схему безопасности Oauth2Secure
, так как бэкенду просто нужно получить значение токена из заголовка запросаи проверьте, если существует на БД.В случае, когда токен создается непосредственно из бэкэнда, поскольку я также предлагаю возможность аутентификации пользователей, которые не используют логин Facebook через имя пользователя и пароль, имеет ли смысл использовать Oauth2Secure
?Чтобы быть более точным, поток паролей пользователя будет таким: когда имя пользователя и пароль действительны в БД, создайте токен, связанный с пользователем, чтобы отслеживать логин пользователя. Есть ли какая-нибудь лучшая схема, которую я должен использовать, так как мне нужно только для обоихслучаи, чтобы проверить, существует ли токен для пользователя на БД.
В разделе Авторизация чванства я должен предоставить client_id и client_secret для аутентификации API.Суть в том, что: -Я не хочу делиться с каким-либо сторонним разработчиком интерфейса секретом своего приложения.-Даже разглашая секрет, конечная точка авторизации находится на бэкэнде, и это возвращает меня к тому, что пользователю нужно взаимодействовать с диалоговым окном входа в Facebook
Большое спасибо!