Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [MySQL][PHP]Licencja - API
Forum PHP.pl > Forum > Przedszkole
alkesz1718
Witam, na podstawie wielu poradników w internecie próbowałem napisać własny skrypt sprawdzający licencję, na początek podam kod który tworzy mi licencję w formacie XXXXX-XXXXX-XXXXX-XXXXX i wysyła do bazy danych:
  1. <?php
  2.  
  3. if (!defined("LICENSE_KEY_INC") ) {
  4. define("LICENSE_KEY_INC",1) ;
  5.  
  6. class license_key{
  7. var $keylen= 20;
  8. var $basechar='23456789ABCDEFGHJKLMNPQRSTUVWXYZ';
  9. var $formatstr= '55555';
  10. var $isvalid="YES";
  11. var $invalid="NO";
  12. var $software="";
  13.  
  14. function codeGenerate($name=""){
  15. $keylen= $this->keylen;
  16. $initlen=$this->initLen();
  17. $initcode=$this->initCode($initlen);
  18. $fullcode=$this->extendCode($initcode,$name);
  19. return $this->formatLicense($fullcode);
  20. }
  21.  
  22. function codeValidate($serial,$name=""){
  23. if(empty($serial)|| $serial=="")return $this->invalid;
  24. $serial=str_replace("-","",$serial);
  25. $serial=strtoupper($serial);
  26. $serial=str_replace(array("0","1","O","I",),
  27. array("","","","",),
  28. $serial);
  29. $keylen= $this->keylen;
  30. $thislen=strlen($serial);
  31. if($keylen<>$thislen)return $this->invalid;
  32. $initlen=$this->initLen();
  33. $initcode=substr($serial,0,$initlen);
  34. $extendedcode=$this->extendCode($initcode,$name);
  35. $fullcode=substr($extendedcode,0,$keylen);
  36. if($fullcode==$serial) return $this->isvalid;
  37. else return $this->invalid;
  38. }
  39.  
  40. function initCode($length=14){
  41. $list=$this->basechar;
  42. $lenlist=strlen($list)-1;
  43. $codestring="";
  44. $length=max($length,1);
  45. if($length>0){
  46. while(strlen($codestring)<$length){
  47. $codestring.=$list[mt_rand(0,$lenlist)];
  48. }
  49. }
  50. return $codestring;
  51. }
  52.  
  53. function extendCode($initcode,$name) {
  54. $software=$this->software;
  55. $p1str=$this->sumDigit($initcode);
  56. $p1str.=$this->add32($initcode,$name."abhishek".$software);
  57. $p1str=strtoupper($p1str);
  58. $p1str=str_replace( array("0","1","O","I",),
  59. array("","","","",),
  60. $p1str);
  61. $p1len=strlen($p1str);
  62. $extrabit="";$i=0;
  63. while(strlen($extrabit)<$this->keylen-2) {
  64. $extrabit.=substr($p1str,$i,1);
  65. $extrabit.=substr($p1str,$p1len-$i-1,1);
  66. $i++;
  67. if (defined('LKM_DEBUG'))echo "$p1str $extrabit<br/>";
  68. }
  69. return $initcode.$extrabit."6F75";
  70. }
  71.  
  72. function formatLicense($serial){
  73. $farray=str_split($this->formatstr);
  74. $sarray=str_split($serial);
  75. $s0=$farray[0];
  76. $s1=$farray[1]+$s0;
  77. $s2=$farray[2]+$s1;
  78. $s3=$farray[3]+$s2;
  79. $s4=$farray[3]+$s3;
  80. $scount=$this->keylen;$sformated="";
  81. for ($i=0;$i<$scount;$i++){
  82. if($i==$s0||$i==$s1||$i==$s2||$i==$s3||$i==$s4)
  83. $sformated.="-";
  84. $sformated.=$sarray[$i];
  85. }
  86. if (defined('LKM_DEBUG')) echo " $serial FORMATED AS $sformated<br/>";
  87.  
  88. return $sformated;
  89. }
  90.  
  91. function initLen(){
  92. $keylen=$this->keylen;
  93. $initlen=intval($keylen/3);
  94. $initlen=max($initlen,1);
  95. return $initlen;
  96. }
  97.  
  98. function add32($a,$b){
  99. $sum=base_convert($a,36,10)+base_convert($b,36,10);
  100. $sum32=base_convert($sum,10,36);
  101. $sum32=str_replace( array("0","1","O","I","o","i"),
  102. array("","","","","","",),
  103. $sum32);
  104. if (defined('LKM_DEBUG'))echo " ADD32 $a + $b = $sum32<br/>";
  105. return $sum32;
  106. }
  107.  
  108.  
  109. function sumDigit($str){
  110. $a=str_split($str);$sum=0;
  111. for($i=0;$i<count($a);$i++)$sum=$sum+base_convert($a[$i],36,10);
  112. $sum=str_replace( array("0","1","O","I","o","i"),
  113. array("AZ","BY","29","38","29","38",),
  114. $sum);
  115. if (defined('LKM_DEBUG'))echo " sumDigit $str = $sum<br/>";
  116. return $sum;
  117. }
  118. }
  119.  
  120. }
  121. ?>


Poniżej moje API:
  1. <?php
  2.  
  3. $config = array(
  4.  
  5. 'host' => 'localhost',
  6. 'user' => 'xxxxxxxx',
  7. 'pass' => 'xxxxxxxx',
  8. 'base' => 'xxxxxxxx'
  9.  
  10. );
  11.  
  12. $db = new mysqli($config['host'], $config['user'], $config['pass'], $config['base']);
  13. if($db->connect_errno) {
  14. exit('Błąd: nie udało się połączyć z bazą danych!');
  15. }
  16. $db->set_charset("utf8");
  17.  
  18. class Main {
  19. public function keygen($domain){
  20. $key[0] = strtoupper(md5($domain));
  21. $key[1] = substr($key[0], 0, 5);
  22. $key[2] = substr($key[0], 5, 5);
  23. $key[3] = substr($key[0], 10, 5);
  24. $key[4] = substr($key[0], 15, 5);
  25. $key[5] = substr($key[0], 20, 5);
  26.  
  27. return $key[1].'-'.$key[2].'-'.$key[3].'-'.$key[4].'-'.$key[5];
  28. }
  29.  
  30. public function getLicInfo($domain){
  31. global $db, $config;
  32.  
  33. $sql = "SELECT * FROM `lic` WHERE `domain` = '{$domain}' LIMIT 1";
  34. $result = $db->query($sql);
  35.  
  36. if($result->num_rows == 1){
  37. return $result->fetch_assoc();
  38. }
  39. return false;
  40. }
  41. }
  42.  
  43. $main = new Main;
  44.  
  45. $domain = "".$_GET['domain']."";
  46. $key = strtoupper($_GET['key']);
  47.  
  48.  
  49.  
  50. if($lic = $main->getLicInfo($domain)){
  51. if($lic['license_status']){
  52. $twokey = $main->keygen($lic['license_domain']);
  53. if($twokey == $key){
  54. $a = 'OK_'.$lic['license_domain'];
  55. } else {
  56. $a = 'ERROR_wrongkey';
  57. }
  58. } else {
  59. $a = 'ERROR_nolicense';
  60. }
  61. } else {
  62. $a = 'ERROR_nolicense';
  63. }
  64.  
  65. echo $a;
  66. exit();
  67. ?>


Struktura bazy wygląda tak:
ID | client | email | software | domain | key | amount
Przykład:
1 | test | test@test.pl | moduł | strona.pl | EYRA2-8965Z-3TSPN-RUAAU | 200

nie wiem co dokładnie mam źle w API ale wchodząc w link: domena.pl/api.php?domain=strona.pl&key=EYRA2-8965Z-3TSPN-RUAAU
zwraca mi wynik ERROR_nolicense

Chcę aby Klient kupując u mnie licencję na dany produkt i wpisując ja na swojej stronie skrypt łączył się z moim API które łączy się z bazą danych i sprawdza czy domena strony jak i podany klucz są zapisane w mojej jak i klucz jest przypisany do tej domeny. Walczę z tym już długi czas i nie wiem co mam źle...

PS. nie wiem czy to ważne ale kod do łączenia się z moim api w skrypcie mam taki:
  1. public function __destruct() {
  2. $request = file_get_contents("http://domain.com/api.php?domain=". $_SERVER['HTTP_HOST'] ."&key=".$this->config->lic_key.");
  3. $status = explode("_", $request);
  4.  
  5. if($status[0] != "OK" && "".$_SERVER['HTTP_HOST']."" != $status[1]){
  6. header("Location: <a href="http://domain.com/&quot%3b%29;" target="_blank">http://domain.com/");</a>
  7. }
  8. }

Pyton_000
A sprawdziłeś chociaż co dostajesz z

$domain = "".$_GET['domain']."";

questionmark.gif
alkesz1718
O ile dobrze zrozumiałem to... dodałem do api na końcu echo $domain; i wyświetla mi adres strony jaki podaję w linku: domena.pl/api.php?domain=strona.pl&key=EYRA2-8965Z-3TSPN-RUAAU
w tym wypadku pokazuje mi: strona.pl

Pyton_000
No to teraz sprawdź co masz w $lic
alkesz1718
Zwraca mi Array i podejrzewam że błąde leży w tym kodzie:
  1. if($lic = $main->getLicInfo($domain)){
  2. if($lic['license_status']){
  3. $twokey = $main->keygen($lic['license_domain']);
  4. if($twokey == $key){
  5. $a = 'OK_'.$lic['license_domain'];
  6. } else {
  7. $a = 'ERROR_wrongkey';
  8. }
  9. } else {
  10. $a = 'ERROR_nolicense';
  11. }
  12. } else {
  13. $a = 'ERROR_nolicense';
  14. }

Ale już nie ogarniam jak to naprawić sad.gif
viking
Skoro wiesz że łapie się else to wiesz że $twokey != $key. Dumpuj sobie dane i idź w górę kodu. W ogóle czemu w destruktorze cokolwiek robisz zwłaszcza header()?
gino
Witam,

mam takie pytanie: czy ten klucz licencyjny ma być generowany losowo czy u Ciebie jest w nim jakiś ukryty sens (kolejność, logika itp)? Pytam, bo klasa strasznie rozbujana, można wygenerować klucz na podstawie np. generowania kluczy GUID funkcją sprintf Mozilla GUID, jedna prosta funkcja i po sprawie, można używając md5 i uniqid rand i tak dalej, parę linijek kodu. Sprawdzić przed zapisem czy aby takiego klucza nie ma już w bazie i po kłopocie.
Poza tym
Kod
$sql = "SELECT * FROM `lic` WHERE `domain` = '{$domain}' LIMIT 1";

dlaczego LIMIT 1? A jak się powtórzy klucz? Prawdopodobieństwo istnieje, małe ale jest. Sprawdzić przed zapisem do bazy.

gino
alkesz1718
viking,
wzorowałem się na różnych przykładach podobnych kodów, nie znam dobrze php dlatego nie wiem gdzie dokładnie jest błąd i jak go naprawić.

gino,
Poniżej daję kod jaki mam podczas generacji tej licencji:
  1. <?php
  2. if(isset($_POST['domain'])) {
  3. $name = trim($_POST['name']);
  4. $email = trim($_POST['email']);
  5. $amount = trim($_POST['amount']);
  6. $domain = trim($_POST['domain']);
  7. $software = "Nazwa produktu";
  8. $numkeys=1;
  9. $keylen=20;
  10.  
  11. //MD5 encode the submitted content
  12.  
  13. include("license_key.class.php");
  14.  
  15. $pass=new license_key();
  16. for($i=0;$i<$numkeys;$i++){
  17. $key= $pass->codeGenerate($name.$software.$domain);
  18.  
  19. }
  20.  
  21. if (!$name|| !$email || !$software || !$domain || !$key || !$amount)
  22. {
  23. echo '';
  24. }
  25.  
  26. @ $db = new mysqli('localhost','xxxxxx','xxxxxx','xxxxxx');
  27.  
  28. if (mysqli_connect_errno())
  29. {
  30. echo 'Połączenie z bazą nie powiodło się. Spóbuj ponownie';
  31. }
  32. $db->query('SET NAMES utf8');
  33. $db->query('SET CHARACTER_SET utf8_unicode_ci');
  34. $zapytanie = "insert into lic values ('".$id."','".$name."', '".$email."', '".$software."', '".$domain."','".$key."', '".$amount."')";
  35. $wynik = $db->query($zapytanie);


Ogólnie to miałem zamiar by licencja była generowana z nazwy domeny, nazwy produktu/modułu oraz nazwy użytkownika (name) na podstawie tych 3 danych ma generować unikalną licencję (chyba tutaj poprawnie mam napisany kod), kod licencyjny w przypadku tego co robię będzie raczej nie możliwy do powtórzenia więc o to się nie martwię.

co do twojego pytania o LIMIT 1 to tak jak napisałem koledze wyżej wzorowałem się na różnych przykładach dostępnych i w internecie.

Byłbym wdzięczny gdyby ktoś pomógł naprawić moje API

Pomoże ktoś? zależy mi na czasie
gino
A to co za twór?
Kod
if($lic = $main->getLicInfo($domain)){
    if($lic['license_status']){
mam na myśli $lic['license_status']? Według kodu odwołujesz się do pola w tabeli bazy danych, którego nie masz.

Kod
    public function getLicInfo($domain){
        global $db, $config;

        $sql = "SELECT * FROM `lic` WHERE `domain` = '{$domain}' LIMIT 1";
        $result = $db->query($sql);

        if($result->num_rows == 1){
            return $result->fetch_assoc();
        }
        return false;
    }


W tej metodzie zwracasz tablice asocjacyjną z zapytania sql, wywalasz to do zmiennej tablicowej $lic. Następnie usiłujesz odczytać pole license_status ( a w zasadzie sprawdzic jego stan) którego nie masz w tabeli. Przynajmniej tej, którą tutaj opisałeś. Albo coś obciąłeś w tablicy albo te klasy to niepełna implementacja, albo wszystkiego nie piszesz, albo pomyliły Ci się zmienne, etc..

gino
alkesz1718
Ok, zmieniłem tą część co podałeś...
  1. if($lic = $main->getLicInfo($domain)){
  2. if($lic['key']){
  3. $twokey = $main->keygen($lic['license_domain']);
  4. if($twokey == $key){
  5. $a = 'OK_'.$lic['license_domain'];
  6. } else {
  7. $a = 'ERROR_wrongkey';
  8. }
  9. } else {
  10. $a = 'ERROR_nolicense - brak licencji';
  11. }
  12. } else {
  13. $a = 'ERROR_nolicense';
  14. }


Teraz pokazuje błąd ERROR_wrongkey, wiem że teraz błąd leży w kodach:
  1. $twokey = $main->keygen($lic['license_domain']);

oraz:
  1. public function keygen($domain){
  2. $key[0] = strtoupper(md5($domain));
  3. $key[1] = substr($key[0], 0, 5);
  4. $key[2] = substr($key[0], 5, 5);
  5. $key[3] = substr($key[0], 10, 5);
  6. $key[4] = substr($key[0], 15, 5);
  7. $key[5] = substr($key[0], 20, 5);
  8.  
  9. return $key[1].'-'.$key[2].'-'.$key[3].'-'.$key[4].'-'.$key[5];
  10. }

Mój generator tworzy klucz na podstawie nazwy użytkownika, nazwy modułu oraz nazwy domeny... w powyżej funkcji widzę że jest tylko sama domena. W generatorze mogę zmienić by klucz był wydawany na podstawie nazwy modułu i adresu strony ale teraz pytanie jak to zrobić by w/w kod zamiast samej domeny obsługiwał nazwę modułu...

Całe te API jest sklejką z kilku poradników jakie znalazłem, nie jestem jakimś profesjonalistą w PHP... wręcz przeciwnie, moja wiedza jest bardzo niska, część funkcji ogarniam a część nie, takie API gdzie inna strona łączy się z stroną autora i sprawdza jakieś dane po czym zwraca informacje by skrypt wykonywał działanie jest czarną magią...
gino
Błąd w dalszym ciągu leży w Twoich if-ach, sprawdzasz pola, których fizycznie nie ma, problem leży jeszcze tutaj:

Kod
$twokey = $main->keygen($lic['license_domain']);
        if($twokey == $key){...


nie masz pola licence_domain w tabeli bazy danych, co to za zmienna $key, która nie występuje nigdzie wcześniej?

Strasznie to przekombinowane jest, klucz jest tylko kluczem, nieważne jak zbudowany, wcale nie musi być akurat z domeny, nazwy itp, bo tak naprawdę nie jest ta wiedza do niczego potrzebna, to tylko ciąg znaków, ważne, żeby był unikalny dal każdego użytkownika..

gino

edit: $key to akurat jest z $_GET wuec jest ok
Pyton_000
Piszessz jakiś kod i nie sprawdzasz co zwraca? Weź człowieku wstaw sobie kilka var_dump() w kodzie i patrze co dostajesz i z czym porównujesz. Trochę samodzielności.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.