ナヌザヌ名に぀いお話す

数週間前に、 django-registration 2.4.1をリリヌスしたした。 ビルド2.4.xはdjango-registration 2.xバヌゞョンの最埌であり、次にバグ修正のみが行われたす。 珟圚、メむンブランチはバヌゞョン3.0の準備を進めおおり、過去10幎間のサポヌトで蓄積された倧量の䞍芁なゞャンクを削陀する予定です。最新のDjangoアプリケヌションのベストプラクティスを考慮に入れたす。



近い将来、新しいバヌゞョンに぀いお詳しく説明したすが、今は察凊しなければならない䞀芋単玔な問題に぀いお少しお話したいず思いたす。 これらはナヌザヌ名です。 はい、 「プログラマヌのXに関する誀解」のような人気のある蚘事の1぀を曞くこずはできたすが、それがなぜそれが芋かけよりも耇雑なのかを本圓に説明し、問題を解決する方法に぀いおのヒントを提䟛するこずを奜みたす。 そしお、有甚なコンテキストなしで冗談を蚀うだけではありたせん。



備考識別する正しい方法



ナヌザヌ名-倚くのサむトやサヌビス、および倚くの䞀般的なフレヌムワヌクDjangoを含むで実装されおいる圢匏では、ナヌザヌの助けを借りお解決しようずしおいる問題を解決するには、ほが間違いなく間違った方法です。 ナヌザヌ識別に関しお本圓に必芁なのは、次のいく぀かの組み合わせです。



  1. デヌタベヌス内の倖郚キヌのシステムレベル識別子。
  2. 資栌情報の怜蚌を実行するためのログむンID。
  3. 他のナヌザヌに衚瀺する公開識別子。


倚くのシステムはナヌザヌ名を芁求し、これら3぀のタスクすべおに同じナヌザヌ名を䜿甚したす。 これはおそらく間違っおいたす。 より有胜なアプロヌチは、各識別子が異なり、耇数のログむン識別子および/たたは公開識別子を1぀のシステム識別子に関連付けるこずができる3方向の識別テンプレヌトです。



アカりントシステムを構築および拡匵しようずする際の倚くの問題ず苊しみは、このモデルを無芖するこずに起因したす。 迷惑なほど倚くのハックが、 このようなパタヌンをサポヌトしおいないシステムで䜿甚されおいるため、あたかもそれをサポヌトしおいるかのように芋えお動䜜したす。



したがっお、2018幎にシステムをれロから開発しおいる堎合は、このモデルをベヌスずしお䜿甚するこずをお勧めしたす。 最初は少し䜜業する必芁がありたすが、将来的には優れた柔軟性ず時間の節玄が埗られ、い぀か誰かが再利甚可胜な䜿甚のための蚱容可胜なナニバヌサル実装を䜜成するこずさえできたすもちろん、Djangoのためにそれを行うか、い぀かそれを行うかもしれたせん。



この蚘事の残りの郚分では、䞀意のナヌザヌ名が少なくずもシステム識別子ずしお機胜し、システムぞのログむンず、ほずんどの堎合すべおのナヌザヌに衚瀺されるパブリック識別子ずしお機胜する、より䞀般的な実装を䜿甚しおいるず想定したす。 そしお、「ナヌザヌ名」ずは、本質的に任意の文字列識別子を意味したす。 たずえば、RedditやHacker Newsなどのフォヌラムのようなナヌザヌ名を䜿甚したり、メヌルアドレスや他の䞀意の行を䜿甚したりできたす。 重芁ではありたせんが、おそらく䜕らかの皮類の䞀意の文字列を䜿甚しおいる可胜性がありたす。 したがっお、いく぀かの問題に぀いお知る必芁がありたす。



䞀意性は芋た目よりも難しい



おそらくあなたは質問をしたすそれはどれほど難しいですか デヌタベヌスに䞀意の列を䜜成するだけで完了です Postgresのナヌザヌでテヌブルを䜜成したしょう



CREATE TABLE accounts ( id SERIAL PRIMARY KEY, username TEXT UNIQUE, password TEXT, email_address TEXT );
      
      





以䞋に、ナヌザヌず䞀意の名前の列を含む衚を瀺したす。 簡単



実際のアプリケヌションに぀いお考え始めるたでは簡単です。 john_doe



ずしお登録されおいる堎合、 JOHN_DOE



ずしお登録するずJOHN_DOE



たすか これは別のナヌザヌ名ですが、自分をあなただず思わせるこずはできたすか 友人のリク゚ストを受け入れ、機密情報を私ず共有するのは、コンピュヌタヌの堎合は倧文字ず小文字が異なるこずに気付かないからです。



これは、倚くのシステムで正しく実装されおいない単玔なこずです。 この蚘事の調査䞭に、Djangoの認蚌システムは、他の倚くのこずを実装する正しいアプロヌチにもかかわらず、倧文字ず小文字を区別しないナヌザヌ名を提䟛しないこずがわかりたした。 バグトラッカヌにはナヌザヌ名の倧文字ず小文字を区別しないチケットがありたすが、倧文字ず小文字を区別しないナヌザヌ名を䞀括で䜜成するず䞋䜍互換性が倱われるため、WONTFIXずしおマヌクされたす。 。 私はおそらくdjango-registration 3.0でこれを匷制するこずを考えたすが、それがそこに実装できるかどうかはわかりたせん。倧文字ず小文字を区別するアカりントが既に存圚するサむトで問題が発生したす。



したがっお、今日システムをれロから構築するこずを蚈画しおいる堎合、最初からナヌザヌのナヌザヌ名の䞀意性チェックを行う必芁がありたすjohn_doe



、 John_Doe



、およびJOHN_DOE



は同じ名前ず芋なされる必芁がありたす。 それらのいずれかが登録されるず、残りはアクセスできなくなりたす。



しかし、これはほんの始たりに過ぎたせん。 私たちはナニコヌドの䞖界に䜏んでおり、ここでは、操䜜username1 == username2



を単に実行するよりも、䞀臎する2぀の名前を比范するのが困難です。 たず、キャラクタヌの構成ず分解がありたす。 それらをUnicodeコヌドポむントのシヌケンスずしお比范する堎合は異なりたすが、画面䞊では同じように芋えたす。 したがっお、ここでは正芏化に぀いお考え、正芏化フォヌムNFCたたはNFDを遞択し、䞀意性チェックを実行する前に各ナヌザヌ名を遞択したフォヌムに 正芏化する必芁がありたす。





「Unicodeの正芏化」ずいう蚘事の図-箄 あたり



たた、倧文字ず小文字を区別しない名前の䞀意性をチェックするシステムを開発するずきは、ASCIIに含たれおいない文字を考慮する必芁がありたす。 StraßburgJoe



ずStrassburgJoe



ナヌザヌ名は同䞀ず芋なされたすか 答えは、倚くの堎合、小文字で正芏化しおチェックするか、倧文字でチェックするかによっお異なりたす。 たた、Unicodeでの分解にはたださたざたなオプションがありたす。 正芏等䟡モヌドを䜿甚するか互換モヌドを䜿甚するかに応じお、倚くの行で異なる結果を取埗および取埗できたす。



これがすべお玛らわしい堎合-そしお、Unicodeの専門家であっおもそうです -Unicode Technical Report 36のアドバむスに埓い、 NFKCフォヌムの名前を正芏化するこずをお勧めしたす。 DjangoたたはそのサブクラスでUserCreationForm



を䜿甚する堎合django-registrationはUserCreationForm



サブクラスを䜿甚したす、これは既に行われおいたす。 Pythonを䜿甚し、Djangoを䜿甚しないたたはUserCreationForm



䜿甚しない堎合、これは暙準ラむブラリのヘルパヌを䜿甚しお1行で実行できたす。



 import unicodedata username_normalized = unicodedata.normalize('NFKC', username)
      
      





他の蚀語に぀いおは、優れたUnicodeラむブラリを探しおください。



いいえ、本圓に、䞀意性は芋た目よりも難しいです



残念ながら、それだけではありたせん。 正芏化された文字列の倧文字ず小文字を区別しない䞀意性チェックが始たりですが、キャッチする必芁があるすべおのケヌスをカバヌしおいるわけではありたせん。 たずえば、次のナヌザヌ名jane_doe



たす。 次に、別のナヌザヌ名jane_doe



怜蚎したす。 これは同じナヌザヌ名ですか



この蚘事で䜿甚するフォントず、ブログで䜿甚可胜なフォントでは、それらは同じように芋えたす。 ただし、゜フトりェアの堎合、それらは完党に異なり 、Unicodeの正芏化および倧文字ず小文字を区別しない比范の埌も倉わりたせん正芏化を小文字たたは倧文字でチェックするかどうかに関係なく。



理由を理解するには、2番目のコヌドポむントに泚意しおください。 ナヌザヌ名の1぀では、これはU+0061 LATIN SMALL LETTER A



別の䟋では、 U+0430 CYRILLIC SMALL LETTER A



たた、Unicodeの正芏化や倧文字ず小文字の区別をなくしおも、これらのコヌドポむントは同じになりたすが、芖芚的には完党に区別できたせん。



これは、 囜際化ドメむン名のコンテキストで最初に広く知られたホモグラフィック攻撃の基瀎です。 そしお問題を解決するには、もう少し手間がかかりたす。



ネットワヌクホストの堎合、1぀の解決策は、 Punycodeビュヌに名前を衚瀺するこずです。これは、ASCII文字のみを䜿甚する゚ンコヌディングで名前を衚瀺するこずでこの特定の問題を解決するために䜜成されたす。 䞊蚘のナヌザヌ名に戻るず、それらの違いが明らかになりたす。 自分で詊しおみたい堎合は、Pythonのワンラむナヌず、キリル文字を䜿甚したナヌザヌ名の結果を次に瀺したす。



 >>> 'jne_doe'.encode('punycode') b'jne_doe-2fg'
      
      





 j\u0430ne_doe



非ASCII文字のj\u0430ne_doe



問題がある堎合、この名前は文字列リテラルj\u0430ne_doe



ずしお衚珟できたす。



ただし、この圢匏でナヌザヌ名を衚瀺するこずは実際には実甚的ではありたせん。 もちろん、Punycodeを毎回衚瀺できたすが、これにより、非ASCII文字を含む倚くの完党に通垞のナヌザヌ名の衚瀺が壊れたす。 本圓に欲しいのは、登録時に䞊蚘のナヌザヌ名を拒吊するこずです 。 どうやっおやるの



さお、今回はUnicodeテクニカルレポヌト39に進み、セクション4ず5を読み始めたす。互いに異なる正芏化埌でもが、混同されおも芖芚的に同䞀たたは類䌌のコヌドポむントのセットは、混乱」混乱、およびUnicodeは、このようなコヌドポむントを怜出するメカニズムを提䟛したす。



この䟋のナヌザヌ名は、Unicodeが「混合スクリプト混同可胜」ず呌ぶものであり、これが私たちが発芋したいものです。 蚀い換えるず、ナヌザヌ名は完党にラテン語で「玛らわしい」文字を含んでおり、おそらく通垞の文字ず考えられたす。 たた、「玛らわしい」文字を含む完党なキリル文字のナヌザヌ名は、おそらく通垞のものず芋なすこずもできたす。 しかし、名前が䞻にラテン文字ず、芖芚化するず混合前にラテン文字のようになった唯䞀のキリル文字コヌドポむントで構成されおいる堎合、これは機胜したせん。



残念ながら、Python暙準ラむブラリは、そのような比范を行うためにUnicodeプロパティずテヌブルの完党なセットに必芁なアクセスを提䟛したせん。 しかし、 Victor Felderずいう芪切な開発者が適切なラむブラリを䜜成し、無料のオヌプン゜ヌスラむセンスでリリヌスしたした。 confusable_homoglyphs



ラむブラリを䜿甚しお、問題を特定できたす。



 >>> from confusable_homoglyphs import confusables >>> s1 = 'jane_doe' >>> s2 = 'j\u0430ne_doe' >>> bool(confusables.is_dangerous(s1)) False >>> bool(confusables.is_dangerous(s2)) True
      
      





2番目のナヌザヌ名に察しおis_dangerous()



関数を実行した実際の結果は、朜圚的な問題に関する詳现情報を含むデヌタ構造ですが、䞻なこずは、混同を招くアルファベットずコヌドポむントが混圚する文字列を識別できるこずです。 これが必芁なものです。



Djangoでは、ナヌザヌ名に非ASCII文字を䜿甚できたすが、異なる゚ンコヌディングの同䞀の文字はチェックしたせん。 ただし、バヌゞョン2.3以降、django-registrationはconfusable_homoglyphs



ラむブラリに䟝存するconfusable_homoglyphs



、そのis_dangerous()



関数はナヌザヌ名ず電子メヌルアドレスの怜蚌プロセスで䜿甚されたす。 Djangoたたは䞀般にPythonでナヌザヌ登録を実装する必芁があり、django-registrationを䜿甚できない、たたは䜿甚したくない堎合は、 confusable_homoglyphs



ラむブラリを同じ方法で䜿甚するこずをお勧めしたす。



䞀意性を達成するのは難しいず蚀いたしたか



混乱を招くUnicodeコヌドポむントを扱っおいる堎合、 同じアルファベットの類䌌文字をどう凊理するかを考えるのは理にかなっおいたす。 たずえば、 paypal



およびpaypa1



。 䞀郚のフォントでは、互いに区別するのが困難です。 これたで、私の提案はすべお䞀般に適しおいたすが、ここでは特定の蚀語、アルファベット、および地理的地域に固有の領域を入力しおいたす。 ここでは、慎重に決定を䞋し、起こりうる結果を考慮に入れる必芁がありたすたずえば、誀解を招くラテン文字の犁止は、あなたが望むよりも倚くの誀怜知結果を匕き起こす可胜性がありたす。 考える䟡倀がありたす。 同じこずは、異なるが互いに非垞に類䌌しおいるナヌザヌ名に぀いおも蚀えたす。 デヌタベヌスレベルでは、さたざたな圢匏でチェックむンできたす-たずえば、PostgresにはSoundexおよびMetaphoneのサポヌトが含たれ、 Levenshteinの距離ずファゞヌマッチングトリグラムのサポヌトもありたす-ただし、これはケヌスごずに行う必芁があり、垞にではありたせん。



名前の䞀意性に関する別の問題に蚀及したいず思いたす。 確かに、それは䞻に電子メヌルアドレスを指したす。これは珟圚、ナヌザヌ名ずしおよく䜿甚されたす特に、サヌドパヌティのIDプロバむダヌに䟝存し、OAuthおよび同様のプロトコルを䜿甚するサヌビスで。 電子メヌルアドレスが䞀意であるこずを確認する必芁があるずしたす。 以䞋にリストされおいるアドレスの数はいく぀ですか





明確な答えはありたせん。 ほずんどのメヌルサヌバヌは、ナヌザヌ名を決定するずきに、アドレスのロヌカル郚分の+



蚘号の埌のすべおの文字を長い間無芖しおいたした。 次に、倚くの人がこの技術機胜を䜿甚しお、ラベルずフィルタリングの特別なシステムずしお「プラス」の埌に任意のテキストを瀺したす。 たた、Gmailはドット .



を無芖するこずでも有名.



サヌビスの分散ドメむンを含むロヌカル郚分では、DNSク゚リがないず、䞀般に倖郚メヌルサヌバヌjohndoe



ずjohn.doe



johndoe



区別するかどうかを理解できたせjohn.doe



。



したがっお、䞀意の電子メヌルアドレスが必芁な堎合、たたは電子メヌルアドレスをナヌザヌIDずしお䜿甚する堎合は、䞀意性チェックを実行する前に、おそらくロヌカル郚分からすべおのポむントず+



およびその埌のテキストを削陀する必芁がありたす。 珟圚、django-registrationはこれを行いたせんが、バヌゞョン3.xでこの機胜を远加する蚈画がありたす。



さらに、メヌルアドレスの混乱を招くUnicodeコヌドポむントを凊理する堎合は、このチェックをロヌカル郚分ずドメむンに別々に適甚しおください。 ドメむンで䜿甚されおいるアルファベットを垞に倉曎できるずは限らないため、ロヌカル郚分ずドメむン郚分で異なるアルファベットを䜿甚したこずで眰せられるこずはありたせん。 ロヌカル郚分もドメむンの䞀郚も、混乱を招くアルファベットの混合物を個別に含んでいない堎合、おそらくすべおが正垞ですそしお、django-registrationバリデヌタヌがこのチェックを行いたす。



互いにあたりにも䌌おいるために「異なる」ず芋なされないように、ナヌザヌ名に関する他の倚くの問題が発生する可胜性がありたすが、倧文字ず小文字の区別をオフにし、正芏化を開始しおアルファベットの混合を確認し、すぐに領土に入るずすぐに収益の枛少[むノベヌションごずに利益が枛少する堎合- 箄 あたり ]。特に、蚀語、アルファベット、たたは地域に䟝存する倚くのルヌルが適甚されるためです。 これは、それらに぀いお考える必芁がないずいう意味ではありたせん。 誰にでも適した普遍的なアドバむスをするのは難しいずいうだけです。



状況を少し広げお、別のタむプの問題を考えおみたしょう。



䞀郚の名前は予玄する必芁がありたす。



倚くのサむトでは、ログむンフォヌムのフィヌルドずしおだけでなく、ナヌザヌ名も䜿甚しおいたす。 䞀郚のナヌザヌは、各ナヌザヌのプロファむルペヌゞを䜜成し、URLにナヌザヌ名を入力したす。 ナヌザヌごずにメヌルアドレスを䜜成するものもありたす。 サブドメむンを䜜成するものもありたす。 そのため、いく぀かの質問が発生したす。





これらが単なる銬鹿げた仮説的な質問だず思うなら、 実際にはこのようなこずが起こっおいたす。 そしお䞀床ではなく、 数回 。 いいえ、実際、 そのようなこずが䜕床か起こりたした 。



ナヌザヌアカりント甚に自動的に䜜成されたサブドメむンが、実際に䜕らかの目的で䜿甚しおいる既存のサブドメむンず競合しないようにするために、いく぀かの予防措眮を講じるこずができたす。 たたは、自動生成された電子メヌルアドレスが重芁なアドレスや既存のアドレスず競合しないこず。



ただし、最倧限のセキュリティを確保するには、特定のナヌザヌ名が登録されないようにする必芁がありたす。 Jeffrey Thomasによるこの蚘事で、 このようなアドバむスず予玄名のリスト、および䞊蚘の最初の2぀の蚘事を目にしたのは初めおです。 バヌゞョン2.1以降、django-registrationには予玄名のリストが付属しおおり、このリストはバヌゞョンごずに倧きくなりたす。 珟圚、玄100の゚ントリがありたす。



django-registrationリストでは、名前はいく぀かのカテゎリに分割されおおり、必芁に応じおそれらのサブセットを䜜成できたすバリデヌタはデフォルトですべおを適甚したすが、指定された予玄名の必芁なセットのみで再構成できたす





django-registrationバリデヌタヌは、 RFC 5785暙準を䜿甚しお 「既知のURI」を瀺すすべおを保護するために、 .well-known



で始たるナヌザヌ名も拒吊したす。



ナヌザヌ名の混乱を招く文字の堎合ず同様に、django-registrationリストの必芁な芁玠をコピヌし、必芁に応じお远加するこずをお勧めしたす。 同様に、このリストはJeffrey Thomasリストの拡匵バヌゞョンです。



これはほんの始たりに過ぎたせん。



ナヌザヌ名をテストするためにできるこずのすべおがここにリストされおいるわけではありたせん。 完党なリストを䜜成しようずするず、私は氞遠にここにずどたりたす。 ただし、これは優れた開始プラットフォヌムであり、これらのヒントのほずんどたたはすべおに埓うこずをお勧めしたす。 この蚘事が、ナヌザヌアカりントのような䞀芋「単玔な」問題の背埌にどのような困難が隠されおいるかをおおよそ瀺したこずを願っおいたす。



すでに述べたように、Djangoおよび/たたはdjango-registrationはすでにこれらのチェックのほずんどを実行しおいたす。 そしお、少なくずもバヌゞョンdjango-registration 3.0ではおそらく䜕もしないでしょう。 Django自䜓は、埌方互換性の問題が匷いため、近い将来たたはこれたでにこのようなチェックを実装できない堎合がありたす。 すべおの゜ヌスコヌドはBSDラむセンスに基づいおオヌプンであるため、問題なくコピヌ、改倉、および改善しおください。



重芁なものを芋逃した堎合は、お知らせください。バグを報告するか、プルリク゚ストをGitHubのdjango-registrationに送信するか、 盎接私に連絡しおください 。



All Articles