.NET での CAPTCHA イメージの作成
Experience Level - Intermediate

これは、自分で簡単なものを作成する方法です。最も複雑ではないかもしれませんが、少なくとも追加のセキュリティ層を提供し、常に変化する結果セットを提供します。
これは、VB.NET と MVC ページ ルーティングを使用して SQL で構築されています。
まず、すべての結果を格納する SQL テーブルを作成する必要があります。使用頻度の高いシステムでは、GUID にインデックスを作成する必要があります。
Create Table
CREATE TABLE [dbo].[captcha]([captchaGUID] [varchar](36) NOT NULL,[captchaValue] [varchar](10) NULL,[captchaDateAdded] [datetime] NULL,[captchaDateGuessed] [datetime] NULL)サービスページを追加
次に、ランダムな文字を生成する関数を作成します。下部をよく見ると、コードはいくつかの数値に対して空の文字列を返します。このようにして、生成される値は常にさまざまな長さになります。
値として 40 を使用する理由は、文字列 (長さ 32) が空白値を返す確率を 5 分の 1 にするためです。
Random Letter Function
CREATE FUNCTION [dbo].[GetLetter](@MyInt INT) RETURNS VARCHAR(1) AS BEGINRETURN (SELECT REPLACE(SUBSTRING('ABCDEFGHJKMNPQRTUVQXYZ0123456789', @MyInt,1),'_',''))ENDGOSELECT dbo.GetLetter(ROUND(RAND()*40,0))サービスページを追加
ここで、レコードを Web サイトに送り返すためのストアド プロシージャを作成します。これは、推測されたキャプチャが生成され、削除される場所でもあります。このコードでは、30 分後に削除されます。
関数を 10 回以上呼び出して値を連結し、古い推測値を削除します。Stored Procedure
CREATE PROC [dbo].[NewCaptchaValue] AS BEGINWHILE (SELECT COUNT(*) FROM captcha WHERE captchaDateGuessed IS NULL)<150BEGIN
INSERT INTO captcha(captchaGUID,captchaValue,captchaDateAdded)SELECT NEWID(),dbo.GetLetter(ROUND(RAND()*40,0))+dbo.GetLetter(ROUND(RAND()*40,0))+dbo.GetLetter(ROUND(RAND()*40,0))+dbo.GetLetter(ROUND(RAND()*40,0))+dbo.GetLetter(ROUND(RAND()*40,0))+dbo.GetLetter(ROUND(RAND()*40,0))+dbo.GetLetter(ROUND(RAND()*40,0))+dbo.GetLetter(ROUND(RAND()*40,0))+dbo.GetLetter(ROUND(RAND()*40,0))+dbo.GetLetter(ROUND(RAND()*40,0)),GETDATE()ENDDELETE FROM captcha WHERE captchaDateGuessed<DATEADD(MINUTE,-30,GETDATE())DECLARE @Newcaptcha VARCHAR(36)=(SELECT TOP 1 captchaGUID FROM captcha WHERE captchaDateGuessed IS NULL)SELECT @NewcaptchaENDサービスページを追加
Pass/Fail の文字列を送り返すことにしました。
Stored Procedure
CREATE PROC [dbo].[CaptchaValue](@captchaGUID VARCHAR(36),@captchaValue VARCHAR(10)) AS BEGINDECLARE @CaptchaValueDB VARCHAR(10)=(SELECT captchaValue FROM captcha WHERE captchaGUID=@captchaGUID)DECLARE @Newcaptcha VARCHAR(36)UPDATE captcha SET captchaDateGuessed=GETDATE() WHERE captchaGUID=@captchaGUIDIF @captchaValue=@CaptchaValueDBBEGINSET @Newcaptcha='Pass'ENDIF @captchaValue<>@CaptchaValueDB OR @CaptchaValueDB IS NULLBEGINSET @Newcaptcha='Fail'ENDSELECT @NewcaptchaENDVisual Studio でアカデミー プロジェクトに切り替える

ここに従うべきいくつかのステップ
- プロジェクトにまだない場合は、スクリーンショットに従って App_Code フォルダーを追加します。
- App_Code フォルダーでマウスの右ボタンを押し、[追加] > [クラス] を選択します。
- ポップアップが表示されます。このクラスを Captcha.vb と呼びます。
この新しい項目を右クリックし、プロパティを選択します。
Public Class 宣言の上に、次の参照を追加します。
Imports System.Drawing
Visual Studio でアカデミー プロジェクトに切り替える
Private Shared Function GenerateLineNumberY() As Integer Dim ret As New Integer ret = (6 * Right((Rnd() * Rnd() * Rnd()), 1)) + 2 Return ret End Function Private Shared Function GenerateLineNumberX() As Integer Dim ret As New Integer ret = (6 * Right((Rnd() * Rnd() * Rnd()), 1)) + 2 Return ret End FunctionVisual Studio でアカデミー プロジェクトに切り替える
Private Shared Function GenerateLineNumberSpace() As Integer Dim ret As New Integer ret = (Right(Rnd(), 1)) + 13 Return ret End Function Private Shared Function GenerateLineNumberHeight() As Integer Dim ret As New Integer ret = (2 * Right((Rnd() * Rnd() * Rnd()), 1)) + 1 Return ret End FunctionVisual Studio でアカデミー プロジェクトに切り替える
Private Shared Function GenerateRandomPenColor() As System.Drawing.Pen Dim mypen As New Pen(Brushes.Cyan) Dim ret As New Integer ret = Right((Rnd() * Rnd() * Rnd()), 1) Select Case ret Case 5, 0, 1 mypen.Color = Color.DarkGray Case 6, 2 mypen.Color = Color.DarkRed Case 7, 3, 9 mypen.Color = Color.DarkOliveGreen Case 8, 4 mypen.Color = Color.DarkOrange End Select Return mypen End Function Private Shared Function GenerateRandomBrushColor() As System.Drawing.SolidBrush Dim myBrush As New SolidBrush(Color.Aqua) Dim ret As New Integer ret = Right((Rnd() * Rnd() * Rnd()), 1) Select Case ret Case 5, 0, 1 myBrush.Color = Color.DarkGray Case 6, 2 myBrush.Color = Color.DarkRed Case 7, 3, 9 myBrush.Color = Color.DarkOliveGreen Case 8, 4 myBrush.Color = Color.DarkOrange End Select Return myBrush End Function Public Shared Function GenerateCaptcha(CaptchaString As String) As Bitmap Dim Height As Integer = 60 Dim Width As Integer = 300 Dim objBitmap As Bitmap Dim objGraphics As Graphics
Dim oPoint As New PointF objBitmap = New Bitmap(Width, Height) objGraphics = Graphics.FromImage(objBitmap) 'Draw Background objGraphics.FillRectangle(Brushes.White, 0, 0, Width, Height) objGraphics.DrawRectangle(Pens.Black, 0, 0, Width - 2, Height - 2) 'Draw Text Dim oFont As New Font("Arial", 20) Dim spac As Integer = 5 Dim stringInt As Integer = 1 While stringInt <= CaptchaString.Length spac = spac + GenerateLineNumberSpace() oPoint = New PointF(spac, GenerateLineNumberHeight) objGraphics.DrawString(Mid(CaptchaString, stringInt, 1), oFont, GenerateRandomBrushColor, oPoint) stringInt = stringInt + 1 End While 'White Lines objGraphics.DrawLine(Pens.White, GenerateLineNumberX, GenerateLineNumberY, Width - GenerateLineNumberX(), Height - GenerateLineNumberY()) objGraphics.DrawLine(Pens.White, GenerateLineNumberX, GenerateLineNumberY, Width - GenerateLineNumberX(), Height - GenerateLineNumberY()) objGraphics.DrawLine(Pens.White, GenerateLineNumberX, GenerateLineNumberY, Width - GenerateLineNumberX(), Height - GenerateLineNumberY()) objGraphics.DrawLine(Pens.White, GenerateLineNumberX, GenerateLineNumberY, Width - GenerateLineNumberX(), Height - GenerateLineNumberY()) objGraphics.DrawLine(Pens.White, GenerateLineNumberX, GenerateLineNumberY, Width - GenerateLineNumberX(), Height - GenerateLineNumberY()) objGraphics.DrawLine(Pens.White, GenerateLineNumberX, GenerateLineNumberY, Width - GenerateLineNumberX(), Height - GenerateLineNumberY()) objGraphics.DrawLine(Pens.White, GenerateLineNumberX, GenerateLineNumberY, Width - GenerateLineNumberX(), Height - GenerateLineNumberY()) objGraphics.DrawLine(Pens.White, GenerateLineNumberX, GenerateLineNumberY, Width - GenerateLineNumberX(), Height - GenerateLineNumberY()) objGraphics.DrawLine(Pens.White, GenerateLineNumberX, GenerateLineNumberY, Width - GenerateLineNumberX(), Height - GenerateLineNumberY()) 'Draw Lines objGraphics.DrawLine(GenerateRandomPenColor, GenerateLineNumberX, GenerateLineNumberY, Width - GenerateLineNumberX(), Height - GenerateLineNumberY()) objGraphics.DrawLine(GenerateRandomPenColor, GenerateLineNumberX, GenerateLineNumberY, Width - GenerateLineNumberX(), Height - GenerateLineNumberY())
objGraphics.DrawRectangle(Pens.Black, 0, 0, Width - 2, Height - 2)
Return objBitmap End Functionサブ RegisterRoutes を見つけて、内部に新しいルート (Routes.MapPageRoute) を追加します。
Sub RegisterRoutes(ByVal Routes As RouteCollection) Routes.MapPageRoute("Captcha", "Captcha/{GUID}", "~/Data/Images/CaptchaService.aspx") End Subサービスページを追加
データ フォルダーを追加するには、次のオプションを使用します。
- ClaytabaseAcademy を右クリックし、[追加] > [新しいフォルダー] オプションを使用して、フォルダーに Data という名前を付けます。
- ここで、Images という名前の別のフォルダーをデータ フォルダーに追加します。
- 次に、CaptchaService.aspx という Web フォームを Images フォルダーに追加します。
このページは、先ほど作成したルート ハンドラによって呼び出されます。
Replace Code
Imports System.Data.SqlClientImports ClaytabaseAcademy.GlobalVariablesImports ClaytabaseAcademy.CaptchaImports System.DrawingImports System.Drawing.ImagingPublic Class CaptchaService Inherits System.Web.UI.Page Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load Dim captchaguid As String = RouteData.Values("GUID").ToString Dim con As New SqlConnection(ConStr) Dim com As New SqlCommand("SELECT captchaValue FROM captcha WHERE captchaGUID='" + captchaguid + "'", con) con.Open() Dim CaptchaBitmap As Bitmap = GenerateCaptcha(com.ExecuteScalar) con.Close() Response.ClearContent() Response.ContentType = "image/bmp" CaptchaBitmap.Save(Response.OutputStream, ImageFormat.Gif) End SubEnd Classサービスページを追加
Claytabase Academy を右クリックして [追加] > [新しいフォルダー] を選択し、プロジェクトのルートに Pages という名前の新しいフォルダーを作成します。
CaptchaView という新しい Web フォームを追加します。
新しい Web ページを作成し、イメージ コントロール、テキスト ボックス、ボタン、hiddenfield、およびラベルをドラッグするか、以下のコードをページの本文 (HTML 部分) にコピーします。<body> <form id="form1" runat="server" style="margin:100px auto;width:300px;padding:10px;background-color:#fff;box-shadow:0 0 3px 0 #222;border-radius: 8px;"> <div style="text-align:center;"> <asp:Image ID="CaptchaImage" runat="server" /> </div> <div style="text-align:center;"> <asp:TextBox ID="captchaEntered" runat="server"></asp:TextBox> </div> <div style="text-align:center;"> <asp:Button ID="captchaSubmit" runat="server" Text="Submit" style="margin:5px auto"/> <asp:HiddenField ID="captchaGuid" runat="server" /> </div> <div style="text-align:center;"> <asp:Label ID="captchaResult" runat="server" Text=""></asp:Label> </div> </form></body>最後のステップは、コードが機能することをテストすることです。このためには、コード ビハインド (右クリック > ビュー コード) に移動し、コード ビハインドを以下のものに更新する必要があります。
これにより、ページの読み込み時に実行されるサブと、追加したボタンのクリックを処理する別のサブが作成されます。
Imports System.Data.SqlClientImports ClaytabaseAcademy.GlobalVariablesPublic Class CaptchaView Inherits System.Web.UI.Page Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load If Not IsPostBack Then Using con As New SqlConnection(ConStr) Using com As New SqlCommand("EXEC dbo.NewCaptchaValue", con) con.Open() Dim Captcha As String = com.ExecuteScalar captchaGuid.Value = Captcha CaptchaImage.ImageUrl = "/Captcha/" + Captcha End Using End Using End If End Sub Protected Sub GetCaptcha(sender As Object, e As EventArgs) Handles captchaSubmit.Click If IsPostBack Then Using con As New SqlConnection(ConStr) Dim valStr As String = Replace(captchaEntered.Text, "'", "''") Dim valGUID As String = Replace(captchaGuid.Value, "'", "''") Response.Write("valStr: " + valStr + "<br>") Response.Write("valGUID: " + valGUID + "<br>") Using com As New SqlCommand("EXEC CaptchaValue '" & valGUID & "','" & valStr & "'", con) con.Open() Dim res As String = com.ExecuteScalar() captchaResult.Text = res End Using Response.Write("EXEC CaptchaValue '" & valGUID & "','" & valStr & "'") End Using End If End SubEnd ClassTest that it has worked by select Build > Build Solution from the Top Menu
You should now be able to test this in a number of ways;- Click on Debug when on the relevant page
- Right Mouse button on the item within the project explorer and selecting View in Browser
- Right Mouse button on the page and select View in Browser
Claytabaseによるウェブサイトのデザイン
これは、当社の Web サイト デザイン サービスの一部である、市場で最も高速で最適化されたシステムの 1 つである Ousia コンテンツ管理システム コードから変更されたコードのセクションです。
これらは、約£500から始まるサイトで利用できます.