ชุมชนคนรักภาษาเบสิค - Visual Basic Community

 ลืมรหัสผ่าน
 ลงทะเบียน
ค้นหา
ดู: 253|ตอบกลับ: 0

[VB.NET] โค้ด VB.NET กับการตรวจสอบการ Login เข้าใช้งานโปรแกรมได้เพียงครั้งละ 1 เครื่อง ด้วยการใช้ GUID

[คัดลอกลิงก์]

329

กระทู้

524

โพสต์

7118

เครดิต

ผู้ดูแลระบบ

ทองก้อน ทับทิมกรอบ

Rank: 9Rank: 9Rank: 9

เครดิต
7118


หน้าจอการทำ Login เข้าไปยัง Google Sheet เพื่อทำการตรวจสอบสิทธิในการใช้งาน และบันทึกค่า GUID ...


Add References ... ต้องติดตั้ง Library เข้าไปใหม่ด้วยครับ ...
คลิปวิดีโอในการใช้งาน Nuget เพื่อทำการติดตั้ง Google API และ Material Skin.2 ... *****



ข้อมูลตัวอย่างใน Google Sheet ...

คลิปวิดีโอในการสร้างและใช้งาน Google App Script ... *****

โค้ด VB.NET กับการตรวจสอบการ Login เข้าใช้งานโปรแกรมได้เพียงครั้งละ 1 เครื่อง ด้วยการใช้ GUID ผ่านทาง Google Sheet ทำงานร่วมกับ Google App Script

GUID (Globally Unique IDentifier) คือ "รหัสเฉพาะที่ไม่ซ้ำกันเลยในระดับโลก" ซึ่งใช้เพื่อระบุสิ่งใดสิ่งหนึ่งแบบเฉพาะเจาะจง เช่น:
- อุปกรณ์แต่ละเครื่อง (เช่น PC, มือถือ)
- ไฟล์, เอกสาร, บันทึกในฐานข้อมูล
- ผู้ใช้ หรือ session ในระบบ
GUID มีความยาว 128 บิต และมักแสดงในรูปแบบข้อความ เช่น 6c483b5b-a74b-4fca-be14-6781b30c6b58

มาดูส่วนของ Google App Script เพื่อทำการอ่านเขียนข้อมูล GUID ลงไปใน Google Sheet ... หาก Google Sheet มีการเปลี่ยนแปลงหลัก (Column) ต้องปรับแต่งค่าตามไปด้วย ...
  1. function doPost(e) {
  2.   const ss = SpreadsheetApp.openById("SpreadSheetID");  // ต้องเปลี่ยนค่านี้ตาม Sheet ที่ใช้งานด้วย
  3.   const sheet = ss.getSheetByName("UserLogin"); // ชื่อ SheetName ต้องเปลี่ยนด้วย
  4.   if (!sheet) {
  5.     return ContentService.createTextOutput("Error: Sheet not found");
  6.   }

  7.   const action = e.parameter.action;
  8.   const username = e.parameter.username;
  9.   const guid = e.parameter.guid;
  10.   const timestamp = e.parameter.timestamp;

  11.   if (action === "update_guid") {
  12.     let range = sheet.getDataRange();
  13.     let values = range.getValues();
  14.     for (let i = 1; i < values.length; i++) { // เริ่มที่ 1 เพราะแถว 0 คือ header
  15.       if (values[i][1] === username) { // Username = คอลัมน์ B
  16.         sheet.getRange(i + 1, 5).setValue(guid);       // GUID = คอลัมน์ E
  17.         sheet.getRange(i + 1, 6).setValue(timestamp);  // Last Ping = คอลัมน์ F
  18.         return ContentService.createTextOutput("GUID Updated");
  19.       }
  20.     }
  21.   } else if (action === "clear_guid") {
  22.     let range = sheet.getDataRange();
  23.     let values = range.getValues();
  24.     for (let i = 1; i < values.length; i++) {
  25.       if (values[i][4] === guid) { // GUID = คอลัมน์ E
  26.         sheet.getRange(i + 1, 5).setValue(""); // ล้าง GUID
  27.         sheet.getRange(i + 1, 6).setValue(""); // ล้าง Last Ping
  28.         return ContentService.createTextOutput("GUID Cleared");
  29.       }
  30.     }
  31.   }

  32.   return ContentService.createTextOutput("Invalid Request");
  33. }
คัดลอกไปที่คลิปบอร์ด


มาดูโค้ดฉบับเต็มกันเถอะ ...

  1. Imports System.Collections.Specialized
  2. Imports System.IO
  3. Imports System.Net
  4. '// Download MaterialSkin.2 packages.
  5. '// https://www.nuget.org/packages/MaterialSkin.2/
  6. Imports MaterialSkin
  7. Imports Microsoft.Win32
  8. Imports Newtonsoft.Json

  9. '// คลิปวิดีโอการรับไฟล์ Credentials เพื่อทำการติดต่อกับ Google Sheets และการกำหนดสิทธิ์การเข้าถึง
  10. '// https://www.youtube.com/watch?v=xdYsctNAGEE

  11. '// คลิปวิดีโอการติดตั้ง Google API และ Material Skin.2
  12. '// https://youtu.be/HqNffWxQKaM

  13. '// คลิปวิดีโอการสร้างและใช้งาน Google App Script
  14. '// https://youtu.be/X1pCwJJ9VpI

  15. '// ------------------------------------------------------------------------------------------------
  16. '// Google Visualization API Reference ... https://developers.google.com/chart/interactive/docs/reference
  17. '// Google Visualization API
  18. '// เป็น API จาก Google ที่ช่วยให้เราสามารถดึงข้อมูลจากแหล่งข้อมูลต่างๆ เช่น Google Sheets หรือไฟล์ข้อมูลอื่นๆ
  19. '// แล้วนำข้อมูลนั้นมา แสดงผลในรูปแบบกราฟ, ตาราง หรือ Visualization ต่างๆบนเว็บได้ง่ายๆ
  20. '// เหมาะสำหรับการสร้างแดชบอร์ด หรือรายงานแบบ Interactive ที่ทำงานบนเว็บ
  21. '// Google Visualization API มีฟอร์แมตข้อมูลเฉพาะที่เรียกว่า DataTable (เหมือนตารางฐานข้อมูล มีคอลัมน์และแถว)
  22. '// เราสามารถดึงข้อมูลผ่าน URL โดยใช้ Google Visualization Query Language (GVQL) ซึ่งคล้าย SQL
  23. '// ------------------------------------------------------------------------------------------------

  24. Public Class frmLogin
  25.     '// ป้อน Spreadsheet ID และชื่อชีต
  26.     Private ReadOnly SpreadsheetId As String = "SPREAD_SHEET_ID"    '// อย่าลืมใส่ค่าของคุณด้วย
  27.     'Private ReadOnly ApplicationName As String = ""   '// ไม่ได้ใช้งาน
  28.     Private ReadOnly SheetName As String = "SHEET_NAME" '// อย่าลืมใส่ค่าของคุณด้วย
  29.     Dim CurrentUsername As String = String.Empty

  30.     Dim MyGuid As String = GetMachineGuid()
  31.     Dim WithEvents Timer1 As New Timer()
  32.     Private Sub frmLogin_Load(sender As Object, e As EventArgs) Handles MyBase.Load
  33.         '// ข้อมูลตัวอย่าง
  34.         txtUserName.Text = "admin"
  35.         txtPassword.Text = "admin"
  36.         With Me
  37.             .MinimumSize = New Point(451, 503)
  38.             .MaximumSize = New Point(451, 503)
  39.         End With
  40.         '// Code sample.
  41.         '// https://www.nuget.org/packages/MaterialSkin.2/
  42.         Dim SkinManager As MaterialSkinManager = MaterialSkinManager.Instance
  43.         SkinManager.AddFormToManage(Me)
  44.         SkinManager.Theme = MaterialSkinManager.Themes.DARK
  45.         SkinManager.ColorScheme = New ColorScheme(Primary.Amber500, Primary.BlueGrey900, Primary.BlueGrey500, Accent.LightBlue200, TextShade.WHITE)

  46.         '// ตัวอย่างของ ColorScheme
  47.         'SkinManager.ColorScheme = New ColorScheme(Primary.Blue300, Primary.Blue500, Primary.Blue500, Accent.Blue400, TextShade.WHITE)
  48.         'SkinManager.ColorScheme = New ColorScheme(Primary.Green600, Primary.Green700, Primary.Green200, Accent.Red100, TextShade.WHITE)
  49.         'SkinManager.ColorScheme = New ColorScheme(Primary.LightBlue600, Primary.LightBlue700, Primary.Green200, Accent.LightGreen700, TextShade.WHITE)
  50.         'SkinManager.ColorScheme = New ColorScheme(Primary.Cyan500, Primary.Cyan700, Primary.Cyan100, Accent.Blue100, TextShade.WHITE)
  51.     End Sub

  52.     Private Sub swPassword_CheckedChanged(sender As Object, e As EventArgs) Handles swPassword.CheckedChanged
  53.         txtPassword.Focus()
  54.         txtPassword.Password = Not swPassword.Checked
  55.     End Sub

  56.     '// ------------------------------------------------------------------------------------------------
  57.     '// เริ่มต้นการเข้าสู่ระบบ
  58.     '// ------------------------------------------------------------------------------------------------
  59.     Private Sub btnLogin_Click(sender As Object, e As EventArgs) Handles btnLogin.Click
  60.         Dim UserName As String = txtUserName.Text.Trim()
  61.         Dim Password As String = txtPassword.Text.Trim()
  62.         If String.IsNullOrEmpty(UserName) OrElse String.IsNullOrEmpty(Password) Then
  63.             MessageBox.Show("กรุณากรอก Username และ Password", "แจ้งเตือน", MessageBoxButtons.OK, MessageBoxIcon.Warning)
  64.             Return
  65.         End If
  66.         '//
  67.         '// ใช้ Google Visualization API เพื่อดึงข้อมูลทั้งหมด
  68.         Dim JsonRaw As String = New WebClient().DownloadString("https://docs.google.com/spreadsheets/d/" & SpreadsheetId & "/gviz/tq?tqx=out:json&sheet=" & SheetName)
  69.         '// ตัดข้อความส่วนหน้าและท้ายออก
  70.         Dim jsonClean As String = JsonRaw
  71.         If jsonClean.StartsWith("/*O_o*/") Then
  72.             Dim startIndex = jsonClean.IndexOf("{")
  73.             Dim endIndex = jsonClean.LastIndexOf("}")
  74.             jsonClean = jsonClean.Substring(startIndex, endIndex - startIndex + 1)
  75.         End If
  76.         '// แปลง JSON
  77.         Dim result = JsonConvert.DeserializeObject(Of GoogleSheetResponse)(jsonClean)
  78.         For Each row In result.table.rows
  79.             Dim uid = row.c(1)?.v?.ToString()
  80.             Dim pwd = row.c(2)?.v?.ToString()
  81.             Dim expireRaw = row.c(3)?.f '// ใช้ .f เพื่ออ่านแบบ dd/MM/yyyy
  82.             Dim storedGuid = row.c(4)?.v?.ToString()
  83.             Dim lastPingStr = row.c(5)?.v?.ToString()
  84.             '// ตรวจสอบ Username และ Password
  85.             If UserName = uid AndAlso Password = pwd Then
  86.                 Dim expireDate As DateTime
  87.                 If DateTime.TryParseExact(expireRaw, "dd/MM/yyyy", New Globalization.CultureInfo("th-TH"), Globalization.DateTimeStyles.None, expireDate) Then
  88.                     If expireDate.Year > 2500 Then expireDate = expireDate.AddYears(-543)
  89.                     '// ตรวจสอบวันที่หมดอายุการใช้งานโปรแกรม
  90.                     If Date.Today > expireDate Then
  91.                         MessageBox.Show("บัญชีหมดอายุ กรุณาติดต่อผู้ดูแลระบบ", "Report Error", MessageBoxButtons.OK, MessageBoxIcon.Stop)
  92.                         Exit Sub
  93.                     End If
  94.                     '// ตรวจสอบ GUID
  95.                     If String.IsNullOrWhiteSpace(storedGuid) OrElse storedGuid = MyGuid Then
  96.                         MessageBox.Show("เข้าสู่ระบบสำเร็จ!", "Report Status", MessageBoxButtons.OK, MessageBoxIcon.Information)
  97.                         CurrentUsername = txtUserName.Text.Trim '// <-- เก็บชื่อผู้ใช้จริงที่ล็อกอินสำเร็จ
  98.                         Call StartPingTimer()    '// เริ่มจับเวลา
  99.                         Call WriteGuid(MyGuid)
  100.                         frmMain.Show()
  101.                         Me.Hide()
  102.                         Return
  103.                     Else
  104.                         MessageBox.Show("บัญชีนี้ถูกล็อกไว้ที่เครื่องอื่น!!!", "Report Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
  105.                         Exit Sub
  106.                     End If
  107.                 End If
  108.             End If
  109.         Next
  110.         MessageBox.Show("Username หรือ Password ไม่ถูกต้อง!!!", "Report Error", MessageBoxButtons.OK, MessageBoxIcon.Warning)
  111.     End Sub

  112.     '// ------------------------------------------------------------------------------------------------
  113.     Sub StartPingTimer()
  114.         Timer1.Interval = 60000 '// 60 วินาที (1 วินาที = 1000 มิลลิวินาที (ms))
  115.         Timer1.Start()
  116.     End Sub

  117.     '// ------------------------------------------------------------------------------------------------
  118.     Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
  119.         WriteGuid(MyGuid)
  120.     End Sub

  121.     '// ------------------------------------------------------------------------------------------------
  122.     '// การเขียนข้อมูล GUID ลงไปใน Google Sheet เมื่อเริ่มต้นทำงานของโปรแกรม
  123.     '// ------------------------------------------------------------------------------------------------
  124.     Sub WriteGuid(guid As String)
  125.         Dim url = "ใส่ค่า URL ที่ได้จาก App Script"
  126.         '// Google Apps Script endpoint
  127.         Dim data As New NameValueCollection()
  128.         data("action") = "update_guid"
  129.         data("username") = CurrentUsername
  130.         data("guid") = guid
  131.         '// วันที่และเวลาแบบ UTC (Coordinated Universal Time) ซึ่งเป็นเวลามาตรฐานโลก ไม่ขึ้นอยู่กับโซนเวลา (Time Zone) ของเครื่องคอมพิวเตอร์
  132.         '// เวลาท้องถิ่นประเทศไทย จะ +7 ทำให้เวลาของไทยจะเร็วกว่าและต่างกับเวลามาตรฐานไป 7 ชั่วโมง
  133.         data("timestamp") = DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss")
  134.         '// หรือจะใช้เวลาท้องถิ่นของเครื่อง (Local Time) แทน DateTime.UtcNow
  135.         'DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture)
  136.         '//
  137.         Using client As New WebClient()
  138.             Try
  139.                 Dim response = client.UploadValues(url, "POST", data)
  140.                 'MessageBox.Show(Encoding.UTF8.GetString(response))

  141.                 '// ดูการตอบสนองหากมี Error อื่นๆ เช่น การเชื่อมต่อเน็ตอยู่หรือไม่
  142.             Catch ex As WebException
  143.                 MessageBox.Show("Error: " & ex.Message)
  144.                 If ex.Response IsNot Nothing Then
  145.                     '// ลองทดสอบการตัดอินเทอร์เน็ตดูครับ
  146.                     Using reader As New StreamReader(ex.Response.GetResponseStream())
  147.                         MessageBox.Show("Detail: " & reader.ReadToEnd())
  148.                     End Using
  149.                 End If
  150.             End Try
  151.         End Using
  152.     End Sub

  153.     Private Sub frmLogin_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
  154.         '// เมื่อปิดโปรแกรมก็ทำการเคลียร์ค่า GUID
  155.         ClearGuid(MyGuid)
  156.     End Sub

  157.     '// ------------------------------------------------------------------------------------------------
  158.     '// การเคลียร์ค่า GUID ใน Google Sheet หลังจากการปิดโปรแกรม
  159.     '// ------------------------------------------------------------------------------------------------
  160.     Sub ClearGuid(guid As String)
  161.         Dim url = "ใส่ค่า URL ที่ได้จาก App Script"
  162.         Dim data As New NameValueCollection()
  163.         data("action") = "clear_guid"
  164.         data("guid") = guid
  165.         Using client As New WebClient()
  166.             client.UploadValues(url, "POST", data)
  167.         End Using
  168.     End Sub

  169.     '// ------------------------------------------------------------------------------------------------
  170.     '// อ่านค่า GUID เครื่องตามขนาดจำนวนบิตของระบบปฏิบัติการ
  171.     '// ------------------------------------------------------------------------------------------------
  172.     Function GetMachineGuid() As String
  173.         Try
  174.             '// ตรวจสอบว่า OS เป็นแบบ 64-bit หรือไม่
  175.             Dim view As RegistryView = If(Environment.Is64BitOperatingSystem, RegistryView.Registry64, RegistryView.Registry32)

  176.             '// เปิด Registry ตามขนาดของ OS
  177.             Dim baseKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, view)
  178.             Dim key = baseKey.OpenSubKey("SOFTWARE\Microsoft\Cryptography")

  179.             If key IsNot Nothing Then
  180.                 Dim machineGuid = key.GetValue("MachineGuid")?.ToString()
  181.                 If Not String.IsNullOrWhiteSpace(machineGuid) Then Return machineGuid
  182.             End If
  183.         Catch ex As Exception
  184.             MessageBox.Show("Error reading MachineGuid: " & ex.Message, "Registry Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
  185.         End Try
  186.         Return Nothing
  187.     End Function

  188.     Private Sub txtUserName_KeyPress(sender As Object, e As KeyPressEventArgs) Handles txtUserName.KeyPress
  189.         '// Press ENTER
  190.         If Asc(e.KeyChar) = 13 Then
  191.             e.Handled = True    '// No beep
  192.             SendKeys.Send("{TAB}")
  193.         End If
  194.     End Sub

  195.     Private Sub txtPassword_KeyPress(sender As Object, e As KeyPressEventArgs) Handles txtPassword.KeyPress
  196.         '// Press ENTER
  197.         If Asc(e.KeyChar) = 13 Then
  198.             e.Handled = True    '// No beep
  199.             SendKeys.Send("{TAB}")
  200.         End If
  201.     End Sub

  202.     Private Sub btnExit_Click(sender As Object, e As EventArgs) Handles btnExit.Click
  203.         Me.Close()
  204.     End Sub

  205.     Private Sub frmLogin_FormClosed(sender As Object, e As FormClosedEventArgs) Handles Me.FormClosed
  206.         Me.Dispose()
  207.         GC.SuppressFinalize(Me)
  208.         Application.Exit()
  209.     End Sub

  210. End Class
คัดลอกไปที่คลิปบอร์ด

ดาวน์โหลดโค้ดต้นฉบับ VB.NET & .Net Framework 4.6.2+ ได้ที่นี่ ...

ขออภัย! โพสต์นี้มีไฟล์แนบหรือรูปภาพที่ไม่ได้รับอนุญาตให้คุณเข้าถึง

คุณจำเป็นต้อง ลงชื่อเข้าใช้ เพื่อดาวน์โหลดหรือดูไฟล์แนบนี้ คุณยังไม่มีบัญชีใช่ไหม? ลงทะเบียน

x
สิ่งที่ดีกว่าการให้ คือการให้แบบไม่มีที่สิ้นสุด
ขออภัย! คุณไม่ได้รับสิทธิ์ในการดำเนินการในส่วนนี้ กรุณาเลือกอย่างใดอย่างหนึ่ง ลงชื่อเข้าใช้ | ลงทะเบียน

รายละเอียดเครดิต

ข้อความล้วน|อุปกรณ์พกพา|ประวัติการแบน|G2GNet.com  

GMT+7, 2025-6-15 23:05 , Processed in 0.227842 second(s), 5 queries , File On.

Powered by Discuz! X3.4, Rev.62

Copyright © 2001-2020 Tencent Cloud.

ตอบกระทู้ ขึ้นไปด้านบน ไปที่หน้ารายการกระทู้