验证码编写_请停止编写您自己的用户验证码

验证码编写

重点 (Top highlight)

Most apps require some sort of authentication. You might be a developer working for a large company on their line-of-business apps, which require limiting access to authorized employees and checking their permissions. Or you might be building a new SaaS app, and you want users to create and maintain their profiles.

大多数应用程序都需要某种身份验证。 您可能是一名在大型公司的业务线应用程序上工作的开发人员,这需要限制对授权员工的访问并检查其权限。 或者您可能正在构建一个新的SaaS应用,并且希望用户创建和维护其个人资料。

In both those cases and more, your first step when building the app will likely be creating the authentication and user management workflows. That is, creating a sign-up form and a login page, at the very least. Authentication is one of the most common features developers working on web apps are asked to implement, yet it’s also one of the most overlooked ones.

在以上两种情况下,构建应用程序的第一步都可能是创建身份验证和用户管理工作流程。 也就是说,至少要创建一个注册表单和一个登录页面。 身份验证是要求开发人员开发的Web应用程序最常见的功能之一,但它也是最被忽略的功能之一。

Building a safe authentication system is a really hard task, much harder than you’d think, and very easy to get wrong. Even worse, mistakes can have catastrophic effects. At its core, user management and authentication require just a few web forms, and it could appear to be a very simple task. However, the devil is in the detail, and building those things securely (and in a privacy-conscious way, when possible or even required) is no small feat.

建立安全的身份验证系统是一项非常艰巨的任务,比您想象的要难得多,而且很容易出错。 更糟糕的是,错误可能会带来灾难性的后果。 从根本上讲,用户管理和身份验证仅需要一些Web表单,这似乎是一项非常简单的任务。 但是,细节在于魔鬼,安全地构建这些东西(在可能或什至需要时以一种注重隐私的方式构建)绝非易事。

身份即服务 (Identity-as-a-Service)

The good news is that you don’t need to roll your own user management and authentication logic. It’s 2020, and we have plenty of valid identity-as-a-service solutions that make it extremely easy to add identities to your application safely.

好消息是您不需要使用自己的用户管理和身份验证逻辑。 到了2020年,我们拥有大量有效的身份即服务解决方案,可以非常轻松地将身份安全地添加到您的应用程序中。

To mention a few popular options (in alphabetic order): Auth0, Azure AD, Google Identity Platform, and Okta.

提及一些流行的选项(按字母顺序): 验证码0 Azure AD Google身份平台 Okta

Additionally, there are social networks’ identity providers too, such as Apple’s, Facebook’s, GitHub’s, Twitter’s, etc. These are very easy for consumers to use and provide apps with access to potentially lots of data right off the bat but sometimes might have negative privacy implications for your users.

此外,也有社交网络的身份提供者,例如AppleFacebookGitHubTwitter等等。这些对消费者来说非常容易使用,并为应用程序提供了访问大量潜在数据的便利,但有时可能带来负面影响对用户隐私的影响。

There’s really no reason why you shouldn’t use an identity provider service. They will save you a lot of development time that you can invest in building your actual app, and they’re very powerful right out of the box. Most importantly, however, they’re significantly safer than rolling your own solution.

确实没有理由不应该使用身份提供者服务。 它们将为您节省大量开发时间,您可以在构建实际的应用程序上进行投资,而且它们非常强大,开箱即用。 但是,最重要的是,它们比推出自己的解决方案安全得多。

安全性高 (Security Is in the Large Numbers)

Most identity provider services offer advanced security features, such as support for multi-factor authentication (MFA), or security certificates or keys (including U2F, FIDO2, WebAuthn, etc).

大多数身份提供者服务都提供高级安全功能,例如支持多因素身份验证(MFA)或安全证书或密钥(包括U2F,FIDO2, WebAuthn等)。

Don’t underestimate the importance of this: according to a report by Microsoft, enabling MFA can prevent 99.9% of account compromise attacks.

不要低估了这一点的重要性:根据Microsoft一份报告 ,启用MFA可以阻止99.9%的帐户入侵攻击。

However, there’s another, lesser-known aspect that makes using an identity provider service safer than rolling your own solution: thanks to their very large number of users, they can see patterns and prevent attacks more easily.

但是,还有另一个鲜为人知的方面使使用身份提供者服务比推出自己的解决方案更安全:由于用户数量众多,他们可以轻松地看到模式并防止攻击。

By having millions of users who perform millions of authentications per day, these large identity providers have gained enough data to build AI-infused models that better identify suspicious patterns.

通过让数以百万计的用户每天执行数百万次身份验证,这些大型身份提供商已经获得了足够的数据来构建注入AI的模型,从而更好地识别可疑模式。

For example, let’s say that one of your users based in Canada signs in from their home, and then two hours later the same account is successfully used in Ukraine. Identity provider services would flag this as suspicious and would deny the sign-in outright, or at least ask for another form of verification (e.g., an MFA token). They can also notify the impacted users and/or the admins.

例如,假设您的一位加拿大用户从他们的家中登录,然后两个小时后,同一帐户在乌克兰成功使用。 身份提供商服务会将其标记为可疑,并直接拒绝登录,或者至少要求其他形式的验证(例如MFA令牌)。 他们还可以通知受影响的用户和/或管理员。

常见异议 (Common Objections)

构建用户管理和身份验证逻辑并不是很困难 (It’s not really hard to build a user management and authentication logic)

Sign-up and login forms are just one side of the issue. You need to deal with a lot more than just building a form to allow users to create an account and type in their credentials.

注册和登录表单只是问题的一方面。 您不仅需要构建一个表格来允许用户创建一个帐户并输入其凭据,还需要处理更多的事情。

To start, you need to implement other business logics, such as enforcing password security rules (but please, listen to the NIST and don’t forcefully make passwords expire at regular intervals and don’t impose creative rules, such as requiring uppercase and lowercase and symbols and so on), validating email addresses and/or phone numbers, and offering users a way to reset their passwords (securely).

首先,您需要实现其他业务逻辑,例如强制实施密码安全规则(但是,请听取NIST的意见, 不要强制使密码定期间隔过期, 也不要强加创意规则 ,例如要求使用大写和小写字母和符号等),验证电子邮件地址和/或电话号码,并为用户提供一种(安全地)重置密码的方法。

There are lots of details to keep in mind while designing those systems, and making mistakes is surprisingly easy: very large companies have been caught not hashing passwords in their databases (or not hashing them properly), accidentally dumping passwords in clear text in log files, having password reset forms that can be exploited too easily with social engineering, etc.

在设计这些系统时,要记住很多细节,而且犯错也非常容易:非常大的公司被发现没有对数据库中的密码进行哈希处理(或对哈希值进行不正确的哈希处理),不小心将密码以明文形式转储到日志文件中,具有可以通过社交工程等轻易利用的密码重置表单。

That managing passwords correctly isn’t easy shouldn’t surprise anyone. But, did you know that usernames are hard too? For example, just because two usernames look identical, doesn’t mean they compare the same. James Bennett’s 2018 talk Hi! My name is… has other really interesting insights on what could go wrong with things as “simple” as usernames.

正确管理密码并不容易,任何人都不应感到惊讶。 但是,您知道用户名也很难吗? 例如,仅因为两个用户名看起来相同, 并不表示它们比较相同 。 詹姆斯·贝内特(James Bennett)2018年的演讲嗨! 我的名字是……对于“简单”的用户名可能出什么问题,还有其他真正有趣的见解。

Lastly, applications can greatly benefit from advanced security features that many providers already offer, including support for multi-factor authentication and security tokens.

最后,应用程序可以从许多提供商已经提供的高级安全功能中受益匪浅,包括对多因素身份验证和安全令牌的支持。

这些服务身份验证服务并不总是免费的,尤其是随着我的应用的增长 (Those services authentication services aren’t always free, especially as my app grows)

You know what else isn’t free? Getting hacked and having to pay the damages, in terms of direct remediation costs (if any), in terms of time spent fixing the app urgently, and not least, in terms of loss of trust from your users.

你知道还有什么不是免费的吗? 就直接修复成本(如果有的话),紧急修复应用程序所花费的时间而言,尤其是在失去用户信任度方面,被黑客入侵并必须赔偿损失。

Even before that, implementing a safe authentication system and maintaining it, operating the user database, etc., all come at the cost of time and resources for both development and operations.

甚至在此之前,实施安全的身份验证系统并对其进行维护,操作用户数据库等,都是以时间和资源为代价进行开发和操作的。

我是一位非常资深的开发人员,我知道如何构建安全的身份验证系统 (I am a very senior developer and I know how to build a safe authentication system)

First of all, congratulations, as really knowing how to build these things safely is less common than you’d think and expect.

首先,恭喜,因为真正了解如何安全地构建这些东西并不像您想像和期望的那么普遍。

If you really are a very experienced developer, however, chances are that your time is best spent working on other parts of your app that deliver more value to your users.

但是,如果您确实是一个非常有经验的开发人员,那么您最好将时间花在开发应用程序的其他部分上,从而为用户带来更多价值。

Or if you really want to work on auth systems, you might consider joining companies like Microsoft, Auth0, Facebook, etc., and work on improving their identity platforms.

或者,如果您真的想在auth系统上工作,则可以考虑加入Microsoft,Auth0,Facebook等公司,并致力于改善其身份平台。

我想保持对用户的控制 (I want to maintain control over my users)

To start, let me ask you: why? Unless you’re building the new Facebook — in which case, yes, data will be your biggest asset and the more you collect, the better — you probably don’t really need it.

首先,让我问你:为什么? 除非您要建立新的Facebook(在这种情况下,是的,否则数据将是您最大的资产,而您收集的越多越好)-您可能实际上并不需要它。

Additionally, collecting more data about your users might even increase your costs to comply with regulations like GDPR. And it will make breaches potentially more damaging and more expensive.

此外,收集有关用户的更多数据甚至可能会增加遵守GDPR等法规的成本。 这将使违规行为更具破坏性,且成本更高。

Most solutions I listed above still let you get deep visibility over your users and what they do.

我上面列出的大多数解决方案仍使您可以深入了解用户及其行为。

Hosted services tend to be a bit sticky, so if you’re concerned about the ability to migrate to something else in the future, you might consider using a self-hosted identity server instead. But remember: those systems are more complex to maintain and often lack the advanced security features possible because of the numbers.

托管服务通常有点粘性,因此,如果您担心将来能否迁移到其他产品,则可以考虑使用自托管身份服务器。 但请记住:这些系统维护起来更加复杂,并且由于数量众多,常常缺少高级安全功能。

如何开始 (How to Get Started)

I hope I convinced you to switch to an identity provider. Now, let’s see how to get started.

我希望我说服您切换到身份提供者。 现在,让我们看看如何开始。

The good news is that all four providers I listed above (Auth0, Azure AD, Google Identity Platform, Okta) and many more leverage the same protocols: OpenID Connect / OAuth 2.0. Both are modern, industry-standard protocols, with client libraries for every programming language and framework.

好消息是,我上面列出的所有四个提供程序(Auth0,Azure AD,Google Identity Platform,Okta)以及更多其他提供程序都使用相同的协议:OpenID Connect / OAuth 2.0。 两者都是现代的行业标准协议,带有用于每种编程语言和框架的客户端库。

At a high level, the steps include:

从高层次上讲,这些步骤包括:

  1. Register your application with the identity provider. They will give you an Application ID (or Client ID) and a Secret Key (or Client Secret).

    向身份提供者注册您的应用程序。 他们将为您提供一个应用程序ID(或客户端ID)和一个密钥(或客户端密钥)。
  2. Define the permissions your app requires. In addition to returning the user’s profile, depending on the identity service, you can also get access to much more data, including the user’s email inbox, their cloud storage, etc. (e.g., via Office 365 or G Suite)

    定义您的应用所需的权限。 除了返回用户的配置文件之外,根据身份服务,您还可以访问更多数据,包括用户的电子邮件收件箱,他们的云存储等(例如,通过Office 365或G Suite)
  3. Include the client library in your app.

    在您的应用程序中包含客户端库。

I won’t try to explain in detail how OpenID Connect works, but the general flow involves the app redirecting the user to a page on the identity provider’s server. The user will complete the authentication flow there and then is redirected to your app, along with a JWT token.

我不会尝试详细解释OpenID Connect的工作原理,但是一般流程涉及应用程序将用户重定向到身份提供者的服务器上的页面。 用户将在那里完成身份验证流程,然后将其与JWT令牌一起重定向到您的应用。

This JWT token, which is cryptographically signed and has a validity limited in time, can be used to maintain a session for your user. That is, for as long as the token is valid, when it is presented to your application, you can treat the request as if coming from the user the token belongs to.

此JWT令牌经过加密签名,并且有效期有限,可用于为用户维护会话。 也就是说,只要令牌是有效的,当令牌被提供给您的应用程序时,您就可以将请求视为来自令牌所属的用户。

The same JWT token also includes claims about the user. These vary depending on the service, but usually they include the user name, their email address, and/or their ID.

相同的JWT令牌还包含有关用户的声明。 这些取决于服务,但通常包括用户名,电子邮件地址和/或ID。

Your application can use those claims to identify the user, and you can use the same user ID to refer to data stored in your application.

您的应用程序可以使用这些声明来标识用户,并且您可以使用相同的用户ID来引用存储在应用程序中的数据。

As mentioned above, JWT tokens are cryptographically signed, so when you verify the token’s signature, you’re guaranteed that no one tampered with the claims.

如上所述,JWT令牌是经过加密签名的,因此,当您验证令牌的签名时,可以确保没有人篡改声明。

在客户端服务器应用程序中使用OpenID Connect (Using OpenID Connect in a client-server app)

The instructions depend heavily on the language or framework you’re using to build your app.

这些说明在很大程度上取决于您用来构建应用的语言或框架。

The jwt.io website has a comprehensive list of libraries to verify JWT tokens.

jwt.io网站上有用于验证JWT令牌的完整库列表。

For some stacks, you can also leverage higher-level solutions, such as express-jwt or passport for Node.js/Express.

对于某些堆栈,您还可以利用更高级别的解决方案,例如Express-jwt或Node.js / Express的通行证

在静态Web应用程序或本机应用程序中使用OpenID Connect (Using OpenID Connect in a static web app or a native app)

Static web apps (also known as JAMstack apps) and native apps (e.g., desktop or mobile) can use OpenID Connect in a slightly different way. In the OAuth 2.0 specification, this is called the implicit flow in the OAuth 2.0 specification.

静态Web应用程序(也称为JAMstack应用程序 )和本机应用程序(例如,台式机或移动设备)可以以略有不同的方式使用OpenID Connect。 在OAuth 2.0规范中,这在OAuth 2.0规范中称为隐式流

The implicit flow does not require using a Client Secret: because your app runs on the client, there’s no way to safely distribute that.

隐式流程不需要使用“客户端机密”:因为您的应用程序在客户端上运行,所以无法安全地分发它。

  1. Your app redirects the user to the authentication endpoint, making sure that the query string contains scope=id_token.

    您的应用将用户重定向到身份验证端点,并确保查询字符串包含scope=id_token

  2. The user completes the authentication flow with the identity provider.

    用户通过身份提供者完成身份验证流程。
  3. The user is redirected to your app, and the JWT session token is appended as a fragment to the page’s URL (the fragment is what follows the # sign). It is in a field called id_token.

    用户被重定向到您的应用,并且JWT会话令牌作为片段附加到页面的URL(该片段在#符号之后)。 它位于一个名为id_token的字段中。

  4. Your app gets the JWT from the URL’s fragment, then validates it. If it’s valid, your user is authenticated, and you can use the claims inside the JWT to get information on the user.

    您的应用程序从URL的片段中获取JWT,然后对其进行验证。 如果有效,则对用户进行身份验证,然后可以使用JWT中的声明获取有关该用户的信息。

To validate a JWT in a static web app, you can use the idtoken-verifier module. Desktop and mobile apps can use similar libraries for the technology you’re using to develop them.

要在静态Web应用程序中验证JWT,可以使用idtoken-verifier模块。 桌面和移动应用可以将类似的库用于您用于开发它们的技术。

When building client-side apps, such as static web apps or native ones, it’s important to ensure that tokens are signed using RSA-SHA256 (in the JWT header, alg must be RS256), which is asymmetric: tokens are signed with a secret key within the identity provider, and your app can verify them using a public key. The other common algorithm, HMAC-SHA256 (or HS256), uses a symmetric key to sign and verify tokens, which cannot safely be distributed to client-side apps.

在构建客户端应用程序(例如静态Web应用程序或本机Web应用程序)时,重要的是确保使用RSA-SHA256(在JWT标头中, alg必须为RS256 )对令牌进行签名,这是不对称的:令牌使用秘密密钥进行签名身份提供商中的密钥,您的应用可以使用公共密钥进行验证。 另一种常见的算法HMAC-SHA256(或HS256 )使用对称密钥来签名和验证令牌,这些令牌无法安全地分发到客户端应用程序。

Your client-side app can then use this JWT in each request made to back-end API servers, usually passed in the Authorization header or in a cookie. In this case, the JWT acts just like any other session token, but with self-contained claims.

然后,您的客户端应用程序可以在对后端API服务器发出的每个请求中使用此JWT,通常是在Authorization标头或cookie中传递该请求。 在这种情况下,JWT的行为就像任何其他会话令牌一样,但是具有独立的声明。

The API server will check the presence of the JWT and validate it again; if the validation succeeded (and the token has not expired), it can consider the user as authenticated and read its user ID from the claims inside the JWT.

API服务器将检查JWT的存在并再次验证。 如果验证成功(并且令牌尚未过期),则它可以将用户视为已通过身份验证,并从JWT内部的声明中读取其用户ID。

翻译自: https://medium.com/better-programming/stop-writing-your-own-user-authentication-code-e8bb50388ec4

验证码编写

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值